Spring JDBC应用程序中的SELECT FOR UPDATE问题

问题描述 投票:0回答:1

我正在使用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

似乎自动提交是在错误的连接对象上设置的。我看得对吗?那些数字12191209是什么?

当一切正常时,日志如下所示:

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

任何帮助将不胜感激。

mysql spring-boot mariadb spring-jdbc spring-transactions
1个回答
0
投票

我不喜欢autocommit=0,因为最终我可能会忘记COMMIT

[SELECT ... FOR UPDATE仅在您正在事务中时适用(autocommit = 0表示您始终在事务中)。

您的常规日志摘要意味着所有连接都在重复设置该值。不,每个连接不受其他连接设置的影响。

您在日志中看到任何COMMIT吗?您是否发行过ROLLBACK?

© www.soinside.com 2019 - 2024. All rights reserved.