首先抛出问题:
① 一个有事务的方法A(insert)中又调用了一个有事务的方法B(insert2),B成功了,A报错.问:数据库有数据么?有几条?
@Transactional
public int insert(Stu stu) {
insert2(stu);
stu.setStuId(GuoUtil.getUUID());
System.out.println(1/0); // 故意制造异常
return stuMapper.insertSelective(stu);
}
@Transactional
public int insert2(Stu stu) {
stu.setStuId(GuoUtil.getUUID());
return stuMapper.insertSelective(stu);
}
经过我的测试:结果数据库一条数据都没有.
首先需要搞明白@Transactional的默认传播行为.
主要我分析了两个:
①REQUIRED
如果存在一个事务,则支持当前事务,如果没有事务则开启一个新的事务。(默认事务)
这个意思就是insert方法之前没有事务,我就开启一个新的事务,到insert2的时候已经有了,就不会创建新的事务,还是用insert的那个事务.所以insert2成功之后到insert的时候有异常,事务回滚,全部回滚掉了.数据库一条数据都没有插入
@Transactional(propagation = Propagation.REQUIRED)
//@Transactional 默认不写
public int insert(Stu stu) {
insert2(stu);
stu.setStuId(GuoUtil.getUUID());
System.out.println(1/0); //故意制造异常
return stuMapper.insertSelective(stu);
}
②REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
这个意思就是insert方法之前没有事务,我就开启一个新的事务,到insert2的时候发现已经有事务了,所以吧insert的事务挂起,自己又开启一个新的事务,运行完insert2方法之后,提交保存到数据库. 再回到insert的时候发现异常,insert事务回滚,但不影响insert2的事务.所以此时数据库有一条数据
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional不生效的情况
- @Transactional 在private 方法是不生效
- 在同一个bean里,嵌套的public方法@Transactional 也不生效
注意一下不生效的情况: private方法加上去不报错,但是没效果;同一个类里面insert方法里面调用insert2方法,insert2方法的事务也是不生效的.
不搞不知道,一搞吓一跳!