gpt4 book ai didi

java - 如何在 hibernate/spring 中使用 LOCK IN SHARE MODE?

转载 作者:行者123 更新时间:2023-11-30 23:39:35 25 4
gpt4 key购买 nike

我在使用 MySQL 和 Hibernate(与 Spring)时遇到了死锁情况。我收到以下异常消息:

could not get or update next value; SQL[null]; nested exception is org.hibernate.exception.LockAcquisitionException ...Deadlock found when trying to get lock; try restarting transaction

我的 MySQL 数据库将其事务隔离级别配置为 READ COMMITTED,我查看了 INNODB 状态以查看发生死锁时发生了什么。本质上,我看到两个事务,其中一个试图从表中选择一行,而另一个试图更新该行。这里争论的表是我的“唯一 ID”表。我有一个公共(public)的根对象,其他@Entity 对象扩展了它。这个根对象定义了“id”属性,并用@Id、@TableGenerator 和@GeneratedValue 注释。

一些深入研究使我相信,将该表上的“select”的 LockMode 设置为 UPGRADE 可能会有所帮助和/或更改“select”,而不是使用“select .... for更新”,它将使用“选择....锁定共享模式”。

如果设置 Lockmode.upgrade 真的有帮助或将“for update”更改为“lock in share mode”,有什么想法吗?其次,我将如何使用 spring + hibernate 执行此操作...我倾向于实现自定义 LoadEventListener(这将扩展 DefaultLoadEventListener)。

最佳答案

我遇到的特殊情况是死锁发生在我的“id 生成器”表中。最终我发现我的应用程序正在使用 org.hibernate.id.MultipleHiLoPerTableGenerator,它构建了 select 语句(该类在内部将其存储在“query”属性中)并添加了“for update”字符串(它实际上是从org.hibernate.dialect.Dialect 类(getForUpdateString 方法)。

这个特定实例的解决方案是让 Id 生成器在从我的 Id 表执行“选择”时使用“共享模式锁定”而不是“更新”。使用自定义方言(即覆盖 getForUpdateString 方法不可行 b/c 我不想一直“锁定在共享模式”,只是在这种情况下)。

因此我必须创建自己的 Id 生成器类。我确实希望 MultipleHiLoPerTableGenerator 更容易扩展(即希望我可以重写“createSelectSql”方法)。

关于java - 如何在 hibernate/spring 中使用 LOCK IN SHARE MODE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4603398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com