org.springframework.transaction.unexpectedRollbackException: Transaction rolled back because itas been marked as roback-ony
本来是这样的代码
两个doSomething方法都加了默认的事务
@Autowired
A aService
@Autowired
B bService
@Transactional
public void deal() {
aService.doSomething();
bService.doSomething();
}
Class A {
@Transactional
public void doSomething() {
}
}
Class B {
@Transactional
public void doSomething() {
}
}
需求修改
bService.doSomething()不能影响整个deal方法的提交
于是改成代码
@Transactional
public void deal() {
aService.doSomething();
try {
bService.doSomething();
} catch (Exception e) {
}
}
想当然地以为即使bService.doSomething抛了异常,只要catch住不外抛,就不会影响deal的事务提交。面事实上确实想当然了。方法执行完后,仍然抛了个异常描述为
org.springframework.transaction.unexpectedRollbackException: Transaction rolled back because itas been marked as roback-ony
原因
因为deal方法与a,bservice代码的执行总共只创建了一个事务,当里层事务出错后,会标记了事务需要回滚,里层事务与外层事务为同一个事务,所以deal方法也会回滚
解决方案
将里层事务使用PropagatiOn.REQUIRES NEW独立出来即可。里面事务如果抛异常,其方法仍然能保持一个原子事务。只要catch住异常,不影响外部事务的提交
Class A {
@Transactional(propagation =PropagatiOn.REQUIRES NEW)
public void doSomething() {
}
}
Class B {
@Transactional(propagation =PropagatiOn.REQUIRES NEW)
public void doSomething() {
}
}