Description
今天做项目的时候发现一个问题,就是我用@Transactional
装饰的方法中,当抛出Exception
或其子类型的时候,并没有回滚。经过一番调研之后发现是设计如此,@Transactional
就是不会针对Exception
进行回滚,除非你显示的声明如下
@Service
public class MainService {
private MyUserMapper myUserMapper;
@Autowired
public MainService(MyUserMapper myUserMapper) {
this.myUserMapper = myUserMapper;
}
@Transactional(rollbackFor = Exception.class)
public void createUser(Long id) throws Exception {
MyUser myUser = new MyUser();
myUser.setId(id);
myUser.setUserName("rollback");
myUserMapper.createMyUser(myUser);
throw new Exception("for rollback");
}
@Transactional
public void createUserNotRollback(Long id) throws Exception {
MyUser myUser = new MyUser();
myUser.setId(id);
myUser.setUserName("Not rollback");
myUserMapper.createMyUser(myUser);
throw new Exception("for rollback");
}
}
在上面的代码中,createUser
因为添加了rollbackFor = Exception.class
会回滚,而下面的createUserNotRollback
这不会,官方文档有明确的说明:
In its default configuration, the Spring Framework’s transaction infrastructure code marks a transaction for rollback only in the case of runtime, unchecked exceptions. That is, when the thrown exception is an instance or subclass of
RuntimeException
. (Error
instances also, by default, result in a rollback). Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration.
想要针对Checked exceptions
也进行回滚的话,就入上面的配置即可。
本文涉及到的代码可以整体在这里查看。
参考
1.https://stackoverflow.com/questions/37310550/spring-transaction-management-not-working-with-spring-boot-mybatis
2.https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-rolling-back
3.https://dzone.com/articles/spring-transaction-management
4.http://ignaciosuay.com/why-is-spring-ignoring-transactional/