ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring事务管理总结

2019-07-24 16:41:34  阅读:256  来源: 互联网

标签:总结 事务管理 事务 Spring methodA 回滚 methodB spring 多线程


spring事务控制的3种方式

编程式事务:直接在代码里手动开启事务,手动提交,手动回滚(灵活控制,重复代码太多)。

声明式事务:使用SpringAop配置事务,但需要注意的是切入点表达式一定要写正确。

注解式事务:直接在Service层的方法上面加上@Transactional注解,一般常用。

Spring事务不能回滚的原因3+2:

事务配置切入点错误:如Service接口中的方法添加了@Transactional(注解不能继承)。

未抛出异常:如try-catch处理时,catch处未手动抛出RuntimeException异常。

异常类型不符:Spring默认捕获的是RuntimeException,当抛出的不是RuntimeException,不能捕获。

在嵌套事务中:在methodA()内部调用了methodB(),此时methodB()的事务管理不生效。

多线程下的事务管理:使用@Transactional 的方法,内包含多线程的使用,则事务失效。

Spring事务不能回滚处理方案

保证事务切入点的正确,特别是编程式事务。

修改spring默认事务回滚类型为Exception。

声明式:<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>

注解式:@Transactional(rollbackFor=Exception.class)

Service层使用了try-catch处理,则需要手动抛出RuntimeException异常,或者手动添加回滚代码。

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();  

只读事务是不会回滚的,即查询方法中的事务不会回滚。

spring嵌套事务失效问题

即ServiceImpl中的methodA(),methodB();controller中调用了methodA(),在methodA()内部调用了methodB(),此时methodB()的事务管理不生效,只有methodA()的生效。

原因是spring是采用代理模式找到目标对象的。在controller中调用methodA()时,通过代理模式加载出来了目标对象,在内部调用methodB()时不属于代理模式调用,此时AOP失效。

spring多线程下事务管理失效

原因:spring 事务是通过LocalThread来保证线程安全的,事务和当前线程绑定,在多线程下事务失效。

事务的基本特性是原子性,而多线程则是多个操作并行处理,是相悖的。

数据库的事务是由CONNECTION来控制..而Spring通过ThreadLocal来绑定当前数据库连接。

处理方案:使用spring的分布式事务jta,重写JtaTransactionManager的doCommit和doRollback方法。

标签:总结,事务管理,事务,Spring,methodA,回滚,methodB,spring,多线程
来源: https://blog.csdn.net/qq_38331606/article/details/91984347

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有