Spring事务失效总结
每天多学一点点~
话不多说,这就开始吧…
1.前言
年底太忙,没什么时间研究细节。近儿得空,看了看之前写的代码,细想之下,发现很多事务其实没生效。。。细思极恐,在这里记录一下,方便日后复习。
2. 默认传播属性Propagation.REQUIRED
2.1. A调B,A加注解,B不加,无论A或B有异常,this调用还是切面调用,默认在一个事务 都回滚
@Transactional(propagation = Propagation.REQUIRED)
public void A() {
testDao.insetShiwu();
this.B();
System.out.println(1 / 0);
}
public void B() {
testDao2.insetShiwu2();
// System.out.println(1 / 0);
}
2.2. A调B,B有异常,B 加注解,A不加,this调用,A B 均插入 B事务失效
public void A() {
testDao.insetShiwu();
this.B();
}
@Transactional(propagation = Propagation.REQUIRED)
public void B() {
testDao2.insetShiwu2();
System.out.println(1 / 0);
}
原因: spring的事务实现是使用了代理类来实现,而这里的this.methodA(),并没有走TestServiceImpl的代理类,所以事务会失效。
如果想要B 的事务生效,则:
- 把methodA()和methodB()分别放到不同的类里。
- 自己注入自己,用注入的实例调用
@Service
public class TestServiceImpl{
@Autowired
private TestServiceImpl testServiceImpl;
public void A() {
testDao.insetShiwu();
testServiceImpl.B();
}
@Transactional(propagation = Propagation.REQUIRED)
public void B() {
testDao2.insetShiwu2();
System.out.println(1 / 0);
}
}
- 获取代理类,利用代理类调用自己类的方法
这个要加上注解:@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@Service
public class TestServiceImpl{
public void A() {
testDao.insetShiwu();
((TestServiceImpl)AopContext.currentProxy()).B();
}
@Transactional(propagation = Propagation.REQUIRED)
public void B() {
testDao2.insetShiwu2();
System.out.println(1 / 0);
}
}
2.3. A调B,B有异常,都 加 注解,无论A或B有异常,this调用还是切面调用,默认在一个事务 都回滚
3. Propagation.REQUIRES_NEW
3.1. A调B,都 加 注解,this调用,A有异常,B是 REQUIRES_NEW 则b事务不生效
这个上面已经解释过了,不再赘述。
3.2. A调B,A有异常,都加注解,B是 REQUIRES_NEW 则b为一个新事物,A回滚,B插入数据,REQUIRES_NEW 生效
@Transactional
public void A() {
testDao.insetShiwu();
((TestServiceImpl)AopContext.currentProxy()).B();
System.out.println(1 / 0);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void B() {
testDao2.insetShiwu2();
}
总结: 外层事务不会影响内部事务的提交/回滚
3.3. A调B,B有异常,都加注解,B是 REQUIRES_NEW 则b为一个新事物,A B 均回滚,REQUIRES_NEW 失效
@Transactional
public void A() {
testDao.insetShiwu();
((TestServiceImpl)AopContext.currentProxy()).B();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void B() {
testDao2.insetShiwu2();
System.out.println(1 / 0);
}
总结: 内部事务的异常,会影响外部事务的回滚
4.结语
世上无难事,只怕有心人,每天积累一点点,fighting!!!