spring事务传播机制

问题描述

最近在项目优化过程中,遇到一个问题:因为前段时间把一个功能单拎出来弄成一个项目,这次优化就是实现代码的解耦,所以相关逻辑代码删除并通过HTTP的方式调用。完成代码优化后,通过jmeter run testCases。发现根据主键ID查询数据返回NULL。


流程图

分析过程

  1. 当发现这个问题,我第一反应会不会是RPC调用出现问题了,查看日志发现不是想象这样,而是实实在在的查询结果为NULL。
  2. 查看代码逻辑,插入逻辑和查询逻辑放在一个大方法里面,大概定位是因为事务没有提交,数据还未持久化到数据库中,进而查看配置文件,关于事务配置。如下:


        


        
        


        
        
            
            
            
            
        

果然直接在类上面声明事务(说明:相当于在该类所有public方法上加上@Transcational注解),进而证实了刚才的猜想。

我感觉这样的配置真的不是最佳实践。不需要的地方也加上了。正常情况下,事务传播机制保证只有外层事务生效,但是总给人的感觉是代码不可控。尤其是遇到特殊情况下,这很难修改,要满足情况,代码写得很丑陋,还得写上一大堆注释,以防后续partner给修改了。

解决方案

插入逻辑新启一个事务Propagation.REQUIRES_NEW,保证数据持久化再查询。

这实际修改过程中,也是走了不少弯路

  1. 同一个类中,事务声明 REQUIRES -> REQUIRES_NEW,事务未生效。
  2. REQUIRES -> REQUIRES_NEW处于不同类中(REQUIRES_NEW所在的方法未实现接口),事务未生效。
  3. REQUIRES -> REQUIRES_NEW处于不同类中(REQUIRES_NEW所在的方法实现接口),事务生效。

说实话,虽然问题得一解决,但是在这过程中还是存在很多疑点,时间空闲点我会好好梳理下并证实。

查找问题过程中,发现这两篇文章不错:

  • https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html
  • https://juejin.im/entry/5a8fe57e5188255de201062b

你可能感兴趣的:(spring事务传播机制)