记一次 Spring 事务配置踩坑记
记一次 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 事务配置踩坑记的更多相关文章
- spring事务配置的坑
基于 <tx> 命名空间的声明式事务管理 前面两种声明式事务配置方式奠定了 Spring 声明式事务管理的基石.在此基础上,Spring 2.x 引入了 <tx> 命名空间,结 ...
- Gitlab Jenkins WebHook 持续集成配置踩坑记
Jenkins相关介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 目的 配置Gitla ...
- react中的路由配置踩坑记
react 路由配置中,如果根路由(/)匹配一个组件,另一个路由(/list)在进行匹配的时候也会匹配到根路由(/),即在 /list 页面展示的时候 / 页面总是展示在上方. 此时如果想进行严格匹配 ...
- vscode 配置踩坑记
vscode-easy-less 遇到问题最好的解决方式是看官网文档,切记!!! 在web开发当中,经常会写less然后编译成css,当然在VS Code当中也有这样的插件(EasyLess), 但是 ...
- Spring @Transactional踩坑记
@Transactional踩坑记 总述 Spring在1.2引入@Transactional注解, 该注解的引入使得我们可以简单地通过在方法或者类上添加@Transactional注解,实现事务 ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
随机推荐
- db2执行计划具体操作
explain 1.如果第一次执行,请先(在dbinst用户下) connect to dbname,执行db2 -tvf $HOME/sqllib/misc/EXPLAIN.DDL建立执行计划表 2 ...
- spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析
更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...
- Xshell配置ssh免密码登录-密钥公钥(Public key)与私钥(Private Key)登录【已成功实例】
本文转自https://blog.csdn.net/qjc_501165091/article/details/51278696 ssh登录提供两种认证方式:口令(密码)认证方式和密钥认证方式.其中口 ...
- EBS MOAC
alter session set nls_language='SIMPLIFIED CHINESE';alter session set nls_language ='AMERICAN'; exec ...
- linux下chmod使用
用法 chmod使用语法 $ chmod [options] mode[,mode] file1 [file2 ...] 使用ls命令的查看文件或目录的属性 $ ls -l file 八进制语法 ch ...
- 免费网络视频监控软件cmsclient
http://www.brickcom.com/products/DetailView.php?modelname=CMS-Client&series=CMS#product-support ...
- Ubuntu中保存iptables防火墙规则
Ubuntu中保存iptables防火墙规则的例子 打开防火墙 ufw disableufw statusufw enable ufw allow 22/tcp ufw reload iptables ...
- Xcode 常用设置
1.main 文件注释 1)main 文件注释修改路径 /Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Proje ...
- [Android App]IFCTT,即:If Copy Then That,一个基于IFTTT的"This"实现
IFCTT,即:If Copy Then That,是一个基于IFTTT(If This Then That)的"This"实现,它打通了"用户手机端操作"与& ...
- C#:注册组件 (cmd)
public class ComRegistor { public static string classID = "CLSID\\{479A1AAC-C148-40BB-9868-A977 ...