2011-01-05 68 views
0

我在使用MySQL和Hibernate(与Spring)时遇到了死锁情况。我收到以下异常消息:如何在休眠/弹簧的情况下使用共享锁定模式?

无法获取或更新下一个值; SQL [null];嵌套异常是 org.hibernate.exception.LockAcquisitionException ...尝试获取 锁时发现死锁;尝试重新启动事务

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

一些四处使我相信,设置LockMode升级为“选择”该表可以帮助和/或改变为更新“选择”,这样,而不是它使用“选择.... “它将使用”选择.... 锁定共享模式“。

任何想法,如果设置Lockmode.upgrade真的会帮助或更改“更新”到“锁定共享模式”?其次,我将如何用spring + hibernate来做到这一点......我倾向于实现一个自定义的LoadEventListener(它将扩展DefaultLoadEventListener)。

+0

我看到这张票http://opensource.atlassian.com/projects/hibernate/browse/HB-398 ..这表明LOCK IN SHARE MODE不会被hibernate直接支持,但它看起来像一个自定义的“选择“可以使用。 – codecraig 2011-01-05 12:28:19

回答

0

我遇到的特殊情况是死锁发生在我的“id generator”表中。最后,我发现,我的应用程序使用它建立起来的SELECT语句(内部该类存储在“查询”属性)的org.hibernate.id.MultipleHiLoPerTableGenerator,并增加了“更新”字符串(它实际上从获得org.hibernate.dialect.Dialect类(getForUpdateString方法)

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

因此,我不得不创建我自己的Id生成器类,我希望MultipleHiLoPerTableGenerator更容易延伸(即希望我可以重写一个'createSelectSql'方法)。