Hibernate объединенные подклассы взаимоблокировки с MSSQL - PullRequest
3 голосов
/ 02 сентября 2010

Я использую Hibernate с Joined-SubClasses, чтобы сопоставить иерархию классов с база данных. К сожалению, это вызывает взаимные блокировки, когда объект обновляется в то время как другой поток пытается загрузить один и тот же объект. С объектами, которые отображаются к одной таблице это не проблема. Кажется, это вызвано тем, как MSSQL приобретает блокировки на таблицах иерархии классов.

Когда Hibernate загружает объект из базы данных, он использует SELECT с JOIN:

SELECT ...
FROM
    subclass
    LEFT JOIN class
        ON ...
WHERE ...

Когда Hibernate обновляет объект этого подкласса, он делает:

UPDATE
    class
SET ...
WHERE ...

UPDATE
    subclass
SET ...
WHERE ...

Проблема в том, что если объект загружен между двумя операторами обновления, он вызывает тупик. Оператор SELECT, кажется, блокирует 2 таблицы одну после другой. Итак, что, кажется, происходит:

  1. Поток 1 загружает объект и устанавливает общие блокировки на обе таблицы
  2. Поток 1 выполняет инструкцию UPDATE для таблицы классов и обновляет замок на столе класса для эксклюзивной блокировки.
  3. Поток 2 пытается загрузить тот же объект, выполнив инструкцию SELECT, он помещает разделяемую блокировку в таблицу подклассов и затем ждет, пока эксклюзивный блокировка на столе класса снята
  4. Поток 1 выполняет инструкцию UPDATE для таблицы подклассов, он хочет обновить его блокировку на таблице подклассов до эксклюзивной блокировки, но таблица уже заблокирована потоком 2, который ожидает поток 1
  5. Поток 2 прерван из-за тупика с потоком 1

График взаимоблокировки выглядит следующим образом: График взаимоблокировки

Эти объекты часто обновляются тихо, и это всегда вызывает взаимные блокировки когда загружен только один объект. Я также пытался воспроизвести проблему с HSQLDB, но тогда он не блокируется, HSQLDB, кажется, блокирует обе таблицы на один раз или ждет, пока он не сможет заблокировать оба, так что кажется, что проблема только происходит с MSSQL.

Каким было бы решение, чтобы избежать этой проблемы с Hibernate без изменения схема (кроме индексов)?

Ответы [ 2 ]

1 голос
/ 02 сентября 2010

Включены ли в флаги трассировки тупиковой ситуации SQL Server 1204 или 1222 ? Это поможет точно определить, какие ресурсы вызывают тупик. См. Статью MSDN по Обнаружение и устранение тупиков для получения дополнительной информации.

Есть ли индексы в этих таблицах? В этом случае могут возникать взаимоблокировки, если приложения получают блокировки для кластеризованного индекса, а затем пытаются получить больше блокировок для той же таблицы путем поиска некластерного индекса.

0 голосов
/ 02 сентября 2010

Мне кажется, что эти обновления должны быть сделаны атомарно в рамках одной транзакции.К сожалению, я не очень разбираюсь в Hibernate, поэтому я оставлю это другим, чтобы указать вам правильное направление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...