记一次 Spring 事务配置踩坑记

问题描述:(SpringBoot + MyBatisPlus)

业务逻辑伪代码如下。理论上,插入数据 t1 后,xxService.getXxx() 方法的查询条件会不满足,会查询不到数据。结果事与愿违,后一次的查询,居然查到了数据。

void saveXxx(){
 xxService.getXxx(); // 查到一条数据 data1
 xxService.insert(); // 插入一条数据 t1
 xxService.getXxx(); // 查到一条数据 data1
}

分析过程:

抛弃业务逻辑,在一个新的 service 中写了一个最简单的测试,查询 --> 插入 --> 查询。为了保证两者具有可比性,sql 都从原 Mapper 中拷贝过去。但是依然重现不了问题。神奇的是出现了如下的情况:

@Transactional
void testMyBatis(){
 yyService.getYyy(); // 查到一条数据 data1
 yyService.insert(); // 插入一条数据 t1
 yyService.getYyy(); // 查不到数据
 xxService.getXxx(); // 查到一条数据 data1
}

理论上,yyService.getYyy() 与 xxService.getXxx() 应该都查不到数据才对,结果只有 xxService.getXxx() 能查到。

开始怀疑事务的问题,是不是 xxService.getXxx() 新开启了一个事务去查询,只有这样,xxService.getXxx() 的查询条件才不受当前事务插入的数据所影响。

检查项目中的事务配置,除了配置了注解式事务外,还有如下的声明式事务配置:

@Bean
public TransactionInterceptor txAdvice() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED );
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
requiredTx.setTimeout(TX_METHOD_TIMEOUT);
Map<String, TransactionAttribute> txMap = new HashMap<>();
txMap.put("add*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("delete*", requiredTx);
txMap.put("get*", readOnlyTx);
txMap.put("query*", readOnlyTx);
source.setNameMap( txMap );
TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);
return txAdvice;
}

就是这一行配置搞的鬼:readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED ); get*开头的方法都加了只读事务,而只读事务是以非事务方式运行,如果当前存在事务,则把当前事务挂起。

这样就解释了为什么 xxService.getXxx() 方法能够查到数据了,它是在当前事务之外查询的数据。

解决办法:

将 readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED ); 去掉。

附:还是使用注解式事务吧 ^_^

记一次 Spring 事务配置踩坑记的更多相关文章

  1. spring事务配置的坑

    基于 <tx> 命名空间的声明式事务管理 前面两种声明式事务配置方式奠定了 Spring 声明式事务管理的基石.在此基础上,Spring 2.x 引入了 <tx> 命名空间,结 ...

  2. Gitlab Jenkins WebHook 持续集成配置踩坑记

    Jenkins相关介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 目的 配置Gitla ...

  3. react中的路由配置踩坑记

    react 路由配置中,如果根路由(/)匹配一个组件,另一个路由(/list)在进行匹配的时候也会匹配到根路由(/),即在 /list 页面展示的时候 / 页面总是展示在上方. 此时如果想进行严格匹配 ...

  4. vscode 配置踩坑记

    vscode-easy-less 遇到问题最好的解决方式是看官网文档,切记!!! 在web开发当中,经常会写less然后编译成css,当然在VS Code当中也有这样的插件(EasyLess), 但是 ...

  5. Spring @Transactional踩坑记

    @Transactional踩坑记 总述 ​ Spring在1.2引入@Transactional注解, 该注解的引入使得我们可以简单地通过在方法或者类上添加@Transactional注解,实现事务 ...

  6. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  7. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  8. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  9. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

随机推荐

  1. MIRUO面试题

    1.c#可以继承string类吗?2.接口可以实现接口吗?抽象类可以实现接口吗?抽象类可以实现实体类吗?3.用C#计算2.5的3次方的方法.4.什么是协同程序?5.GC是什么,如何减少内存,如何加快性 ...

  2. [Visual Studio] 未能完成操作 不支持此接口

    vs2017添加引用时提示“未能完成操作 不支持此接口”, 一般情况下的处理办法:vs2017修复.修复是指重新安装,修改是指版本更新. 如果修复后仍然存在该问题,说明vs2017安装成功后部分功能未 ...

  3. __Linux__操作系统发展史

    常见操作系统win7.Mac.Android.iOS . 操作系统的发展史 1.Unix 1965年之前的时候,电脑并不像现在一样普遍,它可不是一般人能碰的起的,除非是军事或者学院的研究机构,而且当时 ...

  4. hdu2896之AC自动机

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. FDMEMTABLE将修改后的数据序列为JSON

    FDMEMTABLE将修改后的数据序列为JSON procedure TForm1.Button3Click(Sender: TObject); var memtable: TFDMemTable; ...

  6. 用ndk-stack分析应用native程序异常crash掉

    adb logcat | "/home/hxl/bin/android-ndk-r10d/ndk-stack" -sym "/home/hxl/plu/BadGame/p ...

  7. 图解 HTTP 协议

    原文出处: BYSocket (@BYSocket) 一.技术基石及概述 问:什么是HTTP?答:HTTP是一个客户端和服务器端请求和响应的标准TCP.其实建立在TCP之上的. 当我们打开百度网页时, ...

  8. JAVA 自定义注解在自动化测试中的使用

    在UI自动化测试中,相信很多人都喜欢用所谓的PO模式,其中的P,也就是page的意思,于是乎,在脚本里,或者在其它的page里,会要new很多的page对象,这样很麻烦,前面我们也讲到了注解的使用,很 ...

  9. TLS/HTTPS 证书生成与验证

    最近在研究基于ssl的传输加密,涉及到了key和证书相关的话题,走了不少弯路,现在总结一下做个备忘 科普:TLS.SSL.HTTPS以及证书 不少人可能听过其中的超过3个名词,但它们究竟有什么关联呢? ...

  10. linux下无法执行PHP命令,错误 php: command not found

    在linux下执行php时无法执行,报错:php: command not found 解决方法: export PATH=$PATH:/usr/local/php7/bin 可以输入echo $PA ...