我正在使用SELECT ... FOR UPDATE
语句在SpringBoot应用程序中实现行级锁定。数据库:MySQL 5.7.28,连接器-MariaDb Java客户端2.5.2,连接池HikariCP 2.7.9,春季启动版本-2.0.3发布。
持久性是通过Spring JDBC模板而不是JPA实现的。我正在通过在我的DAO方法上拍打@Transactional
批注来使用基于批注的Spring事务管理。事务代理是通过AspectJ编译时编织(@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
)生成的。我确定事务管理器配置正确。
我编写了一些集成测试,这些测试将验证当多个线程竞争更新同一行(应使用SELECT ... FOR UPDATE
锁定)时出现竞争状况的可能性。
现在,测试在95%的时间内都能正常工作,但是,当执行特定顺序的IT时,有一项测试会失败。
我确定测试失败时,不会施加行锁。
我已在服务器上启用MySql查询日志,以帮助进行故障排除。
这是我在第一个线程执行SELECT ... FOR UPDATE
语句时看到的内容:
2020-01-26T12:54:06.681319Z 1219 Query set autocommit=0
2020-01-26T12:54:36.616097Z 1209 Query SELECT _listed_fields_ FROM _my_table_ WHERE id IN ('19qix6lvsfx') FOR UPDATE
似乎自动提交是在错误的连接对象上设置的。我看得对吗?那些数字1219
和1209
是什么?
当一切正常时,日志如下所示:
2020-01-26T13:24:22.940787Z 1243 Query set autocommit=0
2020-01-26T13:24:36.515016Z 1243 Query SELECT _listed_fields_ FROM _my_table_ WHERE id IN ('19xbs7vv53r') FOR UPDATE
任何帮助将不胜感激。
我不喜欢autocommit=0
,因为最终我可能会忘记COMMIT
。
[SELECT ... FOR UPDATE
仅在您正在事务中时适用(autocommit = 0表示您始终在事务中)。
您的常规日志摘要意味着所有连接都在重复设置该值。不,每个连接不受其他连接设置的影响。
您在日志中看到任何COMMIT吗?您是否发行过ROLLBACK?