Spring隔离级别与传播行为
隔离级别
1、脏读:是指一个事务能够读取另外一个事务未提交的数据
2、读写提交
3、可重复读:可以解决脏读、读写提交问题,读取数据后,加入某个用户删除、增加数据,读取的数据将会改变(产生幻读)
4、序列化:解决幻读问题
传播行为
传播行为是指方法之间的调用问题。在大部分的情况下,我们认为事物都应该是一次性全部成功或者全部失败的。例如,业务做成功了,但是财务没有合乎规范,被财务部否决了,这个时候就需要回滚所有事务。但是也会有特殊的场景,比如信用卡还款,进行还款处理,但是我们发现其中的一张卡发生异常,这时我们不能把所有执行过的信用卡数据回滚,而只能回滚出现异常的这张卡。如果将所有执行过还款操作的信用卡回滚,那么就意味着之前按时还款的用户也被认为是不按时还款的,这显然不合理。换句话说,我们在做每一张卡操作的时候都希望有一个独立的事务管控它,使得每一张卡的还款互不干扰。
传播方式 | 含义 | 备注 |
---|---|---|
PROPAGATION_REQUIRED | 如果存在一个事务,则支持当前事务。如果没有事务则开启 | 这是Spring默认的传播行为 |
PROPAGATION_SUPPORTS | 如果存在一个事务,则支持当前事务。如果没有事务,则非事务执行 | - |
PROPAGATION_MANDATORY | 如果已经存在一个事务,则支持当前事务。如果没有一个活动的事务,则抛出异常 | - |
PROPAGATION_REQUIRES_NEW | 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起 | 在信用卡场景中,我们往往需要这个传播行为为每一个卡创建独立的事务 |
PROPAGATION_NOT_SUPPORTS | 总是非事务地执行,并挂起任何存在事务 | - |
PROPAGATION_NEVER | 总是非事务地执行,如果存在一个活动事务,则抛出异常 | - |
PROPAGATION_NESTED | 如果有一个活动的事务存在,则运行在一个嵌套的事务中;如果没有活动事务,则按照TransactionDefinition。PROPAGATION_REQUIRED属性执行 | - |
代码例子
@Service
public class RoleServiceImpl {
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public int insertRoleList(List<Role> roles){
for(Role role : roles){
this.isnertRole(role);//insretRole的注解失效
}
}
}
参考资料
深入浅出Mybatis技术原理与实战