这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
前言
事务是一个需要同时保证原子性、隔离性、一致性和持久性的一个或多个数据库操作
本文会说明,springBoot中两种事务的实现方式,编程式事务配置和声明式事务配置还有切面事务,当然在此之前会说一些基础的东西:事务的四大特征,事务的隔离级别,事务的传播行为
事务的四大特征(ACID)
- 原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部执行,要么均不执行.
- 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致.
- 隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的.
- 持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失.
开启事务
1 | css复制代码@EnableTransactionManagement |
SpringBoot声明式事务
声明式事务@Transactional
可以使用在类上,也可以使用在public
方法上.
如果是使用在类上,则是对所有的public
方法都开启事务,如果类和方法上都有则方法上的事务生效
可以在类上使用
1 | java复制代码@Transactional(rollbackFor=Exception.class) |
更多的是在方法上使用
1 | less复制代码@Override |
@Transactional
的参数
在使用@Transactional
的时候会用到它的一些参数
参数 | 作用 |
---|---|
value | 当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器. |
transactionManager | 当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器. |
propagation | 事务的传播行为,默认值为 Propagation.REQUIRED |
isolation | 事务的隔离级别,默认值为 Isolation.DEFAULT |
timeout | 事务的超时时间,默认值为-1.如果超过该时间限制但事务还没有完成,则自动回滚事务. |
readOnly | 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置read-only 为 true. |
rollbackFor | 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型. |
rollbackForClassName | 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型. |
noRollbackFor | 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型. |
noRollbackForClassName | 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型. |
value
和transactionManager
相同rollbackFor
和rollbackForClassName
相同noRollbackFor
和noRollbackForClassName
相同
事务的隔离级别(isolation)
isolation
中会用到隔离级别
参数 | 事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|
READ_UNCOMMITTED | 读未提交(read-uncommitted) | 是 | 是 | 是 |
READ_COMMITTED | 不可重复读(read-committed) | 否 | 是 | 是 |
REPEATABLE_READ | 可重复读(repeatable-read) | 否 | 否 | 是 |
SERIALIZABLE | 串行化(serializable) | 否 | 否 | 否 |
事务的传播行为(propagation)
propagation
会用到这个传播行文
传播行为 | 解释 |
---|---|
REQUIRED | 如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务. |
SUPPORTS | 如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行. |
MANDATORY | 如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常. |
REQUIRES_NEW | 重新创建一个新的事务,如果当前存在事务,暂停当前的事务. |
NOT_SUPPORTED | 以非事务的方式运行,如果当前存在事务,暂停当前的事务. |
NEVER | 以非事务的方式运行,如果当前存在事务,则抛出异常. |
NESTED | 和REQUIRED效果一样. |
SpringBoo编程式事务
在需要的地方注入TransactionTemplate
1 | java复制代码@Autowired |
然后在代码中使用
1 | typescript复制代码@Override |
这样两个mapper.saveStudent(newOne());
就在一个事务中执行了
SpringBoo切面编程式事务
此种方式基于AOP
功能,所以需要添加
1 | xml复制代码<dependency> |
写配置类
1 | java复制代码@Aspect |
有了这个切面配置类,就不要用在类或者每个方法上使用@Transactional
了,当然方法名前缀要能和设置的匹配上. RuleBasedTransactionAttribute
的参数大致和@Transactional
的参数相同,里面有详细的注释,就不过多解释了
END
切面事务粒度最粗,如果方法名不匹配容易漏方法,声明式事务粒度中等,但是遇到大事务就会出现问题,编程式事务粒度最细,可以考虑在特殊的时候使用它.
1 | arduino复制代码 作者:ZOUZDC |
本文转载自: 掘金