我正在使用Hibernate和Joined-SubClasses将类层次结构映射到a 数据库。不幸的是,当a更新对象时,这会导致死锁 不同的线程正在尝试加载相同的对象。使用映射的对象 这对单个表来说没问题。这似乎是导致MSSQL的方式 获取类层次结构表的锁。
当Hibernate从数据库加载一个对象时,它使用带有JOIN的SELECT:
SELECT ...
FROM
subclass
LEFT JOIN class
ON ...
WHERE ...
当Hibernate更新此子类的对象时,它会:
UPDATE
class
SET ...
WHERE ...
UPDATE
subclass
SET ...
WHERE ...
问题是如果在两个更新语句之间加载一个对象呢 导致僵局。 SELECT语句似乎一次锁定了2个表 另一个。所以似乎发生的事情是:
死锁图如下所示:Deadlock Graph
这些对象经常更新安静,这甚至会导致死锁 只加载一个对象时我也尝试重现这个问题 HSQLDB然后它没有死锁,HSQLDB似乎要么锁定两个表 一次或等到它可以锁定两者,所以它似乎只是一个问题 与MSSQL一起发生。
如何在不修改的情况下避免Hibernate的这个问题 架构(索引除外)?
答案 0 :(得分:1)
你打开了SQL Server deadlock trace flags 1204 or 1222吗?这将有助于确切地确定导致死锁的资源。有关详细信息,请参阅Detecting and Ending Deadlocks上的MSDN文章。
这些表上是否有索引?如果是这样,如果应用程序获取聚簇索引上的锁,然后尝试通过查找非聚集索引来尝试在同一个表上获取更多锁,则会发生死锁。
答案 1 :(得分:0)
在我看来,这些更新需要在单个事务中以原子方式完成。不幸的是,我没有很多关于Hibernate的背景知识,所以我会把它留给其他人指出你在正确的方向。