当前位置: 首页 > 科技观察

大厂数据库事务实践——能否保证事务生效时正确回滚?_0

时间:2023-03-17 14:50:41 科技观察

1AOP实现事务的原理可以理解为用try/catch来包裹@Transactional注解的方法:当方法抛出异常并且满足条件时,catch如果没有异常,事务中可以设置回滚,事务会直接提交。刚才说的条件就是以下两点:只有当异常传播出@Transactional注解的方法时,事务才能被回滚。Spring的TransactionAspectSupport#invokeWithinTransaction方法就是事务处理的逻辑:只有捕获到异常才能进行后续的事务处理。默认情况下,Spring会在出现RuntimeException或Error时回滚事务。检查Spring的DefaultTransactionAttribute。checkedexception一般是业务异常或者其他方法的返回值。如果出现这样的异常,业务可能还是完成了,所以不会主动回滚。Error或RuntimeException代表意外结果,应该回滚2否定教材2.1注册用户案例createUserError1会抛出RuntimeException,但是方法中的catch捕获所有异常createUserError2,注册用户时也会读取readFile。如果读取文件失败,我们希望用户注册的数据库操作也能回滚。这里虽然没有捕获异常,但是因为readFile抛出的是checked异常,createUserError2传播的异常也是checked异常,事务不会回滚。readFilecreateUserError1、2这两个方法虽然可以保证事务生效,但是由于异常处理不当,影响文件操作。当检测到异常时,事务不会回滚。2.2如何修复bug?使用日志验证是否修复成功。针对以上两种情况,修复方案如下。2.2.1修复bug1如果想自己捕获并处理异常,可以手动设置当前事务处于回滚状态。检查日志以确保事务已回滚。事务代码已请求回滚:手动请求回滚。2.2.2修复bug2,注解中写到遇到所有Exception时希望回滚事务。这突破了Spring默认不回滚已检查异常的限制。查看日志确认事务回滚:本例中的事务不仅包括DB操作,还包括IO操作。当IO遇到问题时,希望DB事务也会回滚,保证逻辑一致性。小心别再踩坑了~3小结由于异常处理不当,往往事务确实生效了,但是异常发生时还是不能正确回滚。默认情况下,Spring只有在@Transactional注解的方法出现RuntimeException和Error时才会回滚,所以如果方法捕获到异常,需要通过手写代码来处理事务回滚。如果希望Spring对其他异常进行回滚,可以配置@Transactional注解的rollbackFor和noRollbackFor属性来覆盖Spring的默认配置。本文转载自微信公众号「JavaEdge」,可通过以下二维码关注。转载本文请联系JavaEdge公众号。

猜你喜欢