1 背景
周一回来发现用户中心批量更新手机号未生效,上 Nexus 看了下有没有人动了 lib-datasource(基础架构组的一个组件,简化连接池装配),最新一个版本在上周四,该版本解决了 AutoCommit 的问题,详见参考1。
2 排查过程
-
打断点,确认手机号在批量插入前已经脱敏。
-
联系DBA 输出 general_log,发现最后一步不是 commit,而是 rollback。
-
放开日志级别
,发现程序有 commit。
-
既然 generl_log 现实有 rollback,直接在 java.sql.Connection#rollback() 上打了断点,并保留调用栈
TransactionInterceptor 是事务家的门房。
javax.transaction.TransactionManager,出身高贵,名副其实的官家。
TransactionManager 的大公子 AbstractPlatformTransactionManager 读了几年圣贤书,倒也有模有样,doCommit()、doRollback() 什么的顺手拈来,是其它小儿子的学习榜样。
狐狸精 SpringSessionSynchronization 把 AbstractPlatformTransactionManager 蛊惑了,使他在 triggerBeforeCompletion() 中还没 commit 就把自家 session 给断了(钱都败光了)。
AbstractPlatformTransactionManager 身无分文,只好把传家宝 Connection 贱卖给了包工头DBCP。
包工头DBCP 没有眼光,看这个 Connection 既不是AutoCommit,也不是只读,顺手就砸了它(回滚了 Connection)。
解决方法
- 直接上 HikariCP
- 换别的ORM实现(EBean),甚至 MyBatis、裸JDBC
Reference
[1] [排查 @Transactional 失效](https://www.cnblogs.com/mougg/p/12572773.html