【发布时间】:2020-05-12 02:18:05
【问题描述】:
我正在使用SELECT ... FOR UPDATE 语句在我的 SpringBoot 应用程序中实现行级锁定。数据库:MySQL 5.7.28,连接器 - MariaDb java 客户端 2.5.2,连接池 HikariCP 2.7.9,spring boot 版本 - 2.0.3 Release。
持久性是由 Spring JDBC Template 完成的,而不是由 JPA 完成的。我正在使用基于注释的 Spring Transaction 管理,方法是在我的 DAO 方法上添加 @Transactional 注释。事务代理是通过 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
任何帮助将不胜感激。
【问题讨论】:
标签: mysql spring-boot mariadb spring-jdbc spring-transactions