2011-01-05 73 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'方法)。