携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
相关概念介绍
- 事务作用:在数据层保障一系列的数据库操作同成功同失败
- Spring事务作用:在数据层或**==业务层==**保障一系列的数据库操作同成功同失败
数据层有事务我们可以理解,为什么业务层也需要处理事务呢?
举个简单的例子,
- 转账业务会有两次数据层的调用,一次是加钱一次是减钱
- 把事务放在数据层,加钱和减钱就有两个事务
- 没办法保证加钱和减钱同时成功或者同时失败
- 这个时候就需要将事务放在业务层进行处理。
Spring为了管理事务,提供了一个平台事务管理器PlatformTransactionManager
commit是用来提交事务,rollback是用来回滚事务。
PlatformTransactionManager只是一个接口,Spring还为其提供了一个具体的实现:
从名称上可以看出,我们只需要给它一个DataSource对象,它就可以帮你去在业务层管理事务。其内部采用的是JDBC的事务。所以说如果你持久层采用的是JDBC相关的技术,就可以采用这个事务管理器来管理你的事务。而Mybatis内部采用的就是JDBC的事务,所以后期我们Spring整合Mybatis就采用的这个DataSourceTransactionManager事务管理器。
事务管理
Spring事务管理具体的实现步骤为:
步骤1:在需要被事务管理的方法上添加注解
==注意:==
@Transactional可以写在接口类上、接口方法上、实现类上和实现类方法上
- 写在接口类上,该接口的所有实现类的所有方法都会有事务
- 写在接口方法上,该接口的所有实现类的该方法都会有事务
- 写在实现类上,该类中的所有方法都会有事务
- 写在实现类方法上,该方法上有事务
- ==建议写在实现类或实现类的方法上==
步骤2:在JdbcConfig类中配置事务管理器
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
注意: 事务管理器要根据使用技术进行选择,Mybatis框架使用的是JDBC事务,可以直接使用DataSourceTransactionManager
步骤3:开启事务注解
在SpringConfig的配置类中开启
//开启注解式事务驱动
@EnableTransactionManagement
知识点1:@EnableTransactionManagement
| 名称 | @EnableTransactionManagement |
|---|---|
| 类型 | 配置类注解 |
| 位置 | 配置类定义上方 |
| 作用 | 设置当前Spring环境中开启注解式事务支持 |
知识点2:@Transactional
| 名称 | @Transactional |
|---|---|
| 类型 | 接口注解 类注解 方法注解 |
| 位置 | 业务层接口上方 业务层实现类上方 业务方法上方 |
| 作用 | 为当前业务层方法添加事务(如果设置在类或接口上方则类或接口中所有方法均添加事务) |
Spring事务角色
重点要理解两个概念,分别是事务管理员和事务协调员。
- 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
- 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法
==注意:==
目前的事务管理是基于DataSourceTransactionManager和SqlSessionFactoryBean使用的是同一个数据源。
Spring事务属性
事务配置
上面这些属性都可以在
@Transactional注解的参数上进行设置。
-
readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true。
-
timeout:设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。
-
rollbackFor:当出现指定异常进行事务回滚
-
noRollbackFor:当出现指定异常不进行事务回滚
-
思考:出现异常事务会自动回滚,这个是我们之前就已经知道的
-
noRollbackFor是设定对于指定的异常不回滚,这个好理解
-
rollbackFor是指定回滚异常,对于异常事务不应该都回滚么,为什么还要指定?
- 这块需要更正一个知识点,并不是所有的异常都会回滚事务
-
Spring的事务只会对Error异常和RuntimeException异常及其子类进行事务回顾,其他的异常类型是不会回滚的,例如:IOException不符合上述条件所以不回滚
-
rollbackForClassName等同于rollbackFor,只不过属性为异常的类全名字符串
-
noRollbackForClassName等同于noRollbackFor,只不过属性为异常的类全名字符串
-
isolation设置事务的隔离级别
- DEFAULT :默认隔离级别, 会采用数据库的隔离级别
- READ_UNCOMMITTED : 读未提交
- READ_COMMITTED : 读已提交
- REPEATABLE_READ : 重复读取
- SERIALIZABLE: 串行化
事务传播行为
事务传播行为:事务协调员对事务管理员所携带事务的处理态度。
通俗来讲就是,事务管理员开启了事务,事务协调员可以选择加入也可以选择不加入,加入了就成为一个事务,不加入就可以自己新建事务