当前位置:网站首页>建议自查!MySQL驱动Bug引发的事务不回滚问题,也许你正面临该风险!
建议自查!MySQL驱动Bug引发的事务不回滚问题,也许你正面临该风险!
2022-06-22 14:05:00 【InfoQ】

背景
- commons-db : 我们内部维护的,是一个采用注解驱动的 Spring 生态下的大多数资源管理组件。组件给每个 DataSource 预设了些性能优化的默认值,没有全部列出,不过包含了影响问题走向的属性(useLocalSessionState),如下:
Properties defaultProperties = new Properties();
defaultProperties.put("prepStmtCacheSize", 300);
defaultProperties.put("prepStmtCacheSqlLimit", 2048);
defaultProperties.put("useLocalSessionState", true);
defaultProperties.put("cacheResultSetMetadata", true);
defaultProperties.put("elideSetAutoCommits", true);
- java-project : 用来测试组件功能的项目,会作为和出现问题的项目做行为测试对比。spring-boot:2.5.4、mysql-connector-java:8.0.26
- store:游戏库项目,正是这个项目发现了问题。spring-boot:2.6.6 、mysql-connector-java:8.0.28
- 阿里云 RDS (MySQL): 阿里云 MySQL 默认的隔离级别为 READ_COMMITTED,而 MySQL 默认的隔离级别为 REPEATABLE_READ
问题
@Transactional
@DataSource(type = Type.MASTER,value = "developer")
public void addUser(ApolloUser user){
userRepository.save(user);
int i = 1/0; //抛异常
}
- 具体表现为:执行 addUser 方法,当 1/0 抛出 RuntimeException 类型异常时,user 对象还是添加成功了。一句话总结就是,【事务回滚不生效了】。
假设
- 假设 1:曾假设过是不是 @Transactional 的 aop 没生效,导致并未开启显式事务。
- 假设 1 不成立,因为在开启了 debug 日志模式后,清晰地输出了事务每个阶段的行为日志,如:

- 假设 2:考虑到使用了 commons-db , 如果框架层连接管理问题,导致了事务的开启、事务回滚时获取到的连接不一致,也有可能导致这个问题。
- 假设 2 不成立:马上就否了,因为从上面日志上可以看到连接是同一个连接。而且不同连接执行非预期的开启、回滚事务操作应该会有异常才是。
转机
转机 1
转机 2
@Transactional(isolation = Isolation.REPEATABLE_READ)
@DataSource(type = Type.MASTER,value = "developer")
public void addUser(ApolloUser user){
userRepository.save(user);
int i = 1/0;
}
第一个解决方法
转机 3

分析
- 1、在添加了 @Transactional 的方法执行前,会执行事务管理器(DataSourceTransactionManager)的 doBegin 方法创建一个事务,在 doBegin 方法里,会设置 autoCommit = false。会判当前隔离级别是否和用户定义的一致,否则就更新隔离级别。

- 2、方法执行失败后,会执行事务管理器(DataSourceTransactionManager)的 doRollback 方法回滚事务。
定位问题
- 事务回滚失败时,事务流程并未执行 SET autocommit=0 指令。


- useLocalSessionState:维护本地 sessionState , 在需要判断 【事务提交模式】、【隔离级别】设置时,获取本地状态,而不是每次像 MySQL Server 发起询问。
解密
第二个解决方法
useLocalSessionState=false
auto-commit=false
解释为啥 isolation 设置成 Isolation.REPEATABLE_READ 会生效
public boolean isAutocommit() {
return (this.statusFlags & 2) != 0;
}
public boolean isAutoCommit() {
return this.autoCommit;
}
- 转机 2:当设置隔离级别为 REPEATABLE_READ 时,事务回滚生效了。是因为当用户定义的隔离级别 RR 和默认的 RC 不一致时,会触发 session 设置新的隔离级别,此时也会将 statusFlags = 0 更新为 statusFlags = 2. 故在调用 isAutocommit () 返回 true ,满足了执行 SET autocommit=0 指令的条件。
复现问题
- 升级 spring-boot:2.6.6 版本和 store 保持一致:问题复现了
- 保持 spring-boot:2.5.4,调整 mysql-connector-java:8.0.28 :问题也复现了
确认 bug
- https://github.com/mysql/mysql-connector-j

修复
- 8.0.29 release:https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/news-8-0-29.html
- A connection did not maintain the correct autocommit state when it was used in a pool with useLocalSessionState=true. (Bug #106435, Bug #33850099)
最终解决方法
结语
边栏推荐
- Zhongshanshan: engineers after being blasted will take off | ONEFLOW u
- MySQL learning notes 2022
- Those confusing user state & kernel state
- flutter video_player實現監聽和自動播放下一首歌曲
- [graduation project] Research on emotion analysis based on semi supervised learning and integrated learning
- visual studio开发过程中常见操作
- 数据资产管理:数据发现,发现什么,怎么发现?
- 同花顺开户难么?网上开户安全么?
- RealNetworks vs. 微软:早期流媒体行业之争
- 我靠副业一年全款买房:那个你看不起的行业,未来十年很赚钱!
猜你喜欢

我靠副业一年全款买房:那个你看不起的行业,未来十年很赚钱!

Are there many unemployed people in 2022? Is it particularly difficult to find a job this year?

天安科技IPO被终止:曾拟募资3.5亿 复星与九鼎是股东

Good wind relies on strength – code conversion practice of accelerating SQL Server Migration with babelfish

What is the value of a website? Why build an independent station

Common operations in Visual Studio development

Recommendation of individual visa free payment scheme

RealNetworks vs. Microsoft: the battle in the early streaming media industry

Charles 乱码问题解决

Method of using inout signal in Verilog
随机推荐
FreeRTOS task priority and interrupt priority
Token processing during API encapsulation
那些没考上大学的人,后来过的怎样
Sikulix select the picture of relative position (advanced version)
鸿世电器冲刺创业板:年营收6亿 刘金贤股权曾被广德小贷冻结
FPGA collects DHT11 temperature and humidity
加密市场进入寒冬,是“天灾”还是“人祸”?
历时100天、小鱼搭建了个机器人交流社区!!现公开邀请版主中!
mysql的concat()函数如何用
同花顺开户难么?网上开户安全么?
Charles 乱码问题解决
壹连科技冲刺深交所:年营收14亿 65%收入来自宁德时代
phpStudy 2016搭建-pikachu靶场
After 100 days, Xiaoyu built a robot communication community!! Now invite moderators!
时隔17年,刘亦菲再次刷屏式爆红:普通人不想被淘汰,也要懂得这件事
Verilog使用inout信号的方法
Bochs software usage record
What does password security mean? What are the password security standard clauses in the ISO 2.0 policy?
Mobile learning notes of u++ programming
Struggle, programmer chapter 50: a bosom friend in the sea