propagation为什么打不开

首页 > 实用技巧 > 作者:YD1662023-07-30 22:05:42

@Transactional注解属性rollbackFor设置错误导致注解失效

rollbackFor可以指定能够触发事务回滚的异常类型。Spring默认抛出了unchecked异常(继承自RuntimeException)或者Error才会回滚事务。若事务中抛出了其他类型的异常,但却期望Spring能够回滚事务,就需要指定rollbackFor属性,否则就会失效。

同一类中方法调用,导致@Transactional失效

比如类demo中有方法A和B,方法B中使用@Transactional注解,方法A没有注解,但是demo类通过方法A调用方法B,像这种间接调用会导致方法B中的@Transactional事务注解失效。

失效原因:只有当事务方法被当前类以外的代码调用时,才会有Spring生成的代理对象管理。(Spring AOP代理机制造成的)。

实例验证:demo中构造场景为在同一个类中,在test方法中添加@Transactional注解,querRiskScore方法中不添加该注解,然后在querRiskScore方法中调用test方法;观察下多个插入操作是否会因为异常而中断回滚;

propagation为什么打不开,(5)

▪运行结果如下,还是通过构造的单号不存在订单查询为空触发异常,观察数据库发现,第一次数据库插入操作已经执行成功第二次数据插入操作失败,并没有因为异常而触发事务操作,故而验证@Transactional注解方法间的调用会失效

propagation为什么打不开,(6)

propagation为什么打不开,(7)

多线程任务可能导致@Transaction案例失效

失效原因:线程不属于Spring托管,故线程不能够默认使用Spring的事务,也不能获取Spring注入的bean,在被Spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。

异常被方法内catch捕获导致@Transactional失效

比如B方法内部抛了异常,而A方法此时try-catch了B方法的异常,则该事务不能正常回滚。

失效原因:因为B方法中抛出异常以后,标识当前事务需要rollback,但是A方法中由于你手动的捕获这个异常并进行处理,A方法认为当前事务应该正常commit,此时就出现前后不一致,会抛出org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only异常。

实例验证:这个场景的本质还是异常被捕获导致无法正常的抛出,进而导致@Transactional注解无法正常工作,我简化了下demo实例场景,构造场景如下:在querRiskScore方法中添加@Transactional注解,然后在querRiskScore方法中对异常进行捕获;观察下多个插入操作是否会因为异常而中断回滚;

propagation为什么打不开,(8)

上一页123下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.