Nhibernate: генерирует операторы вставки, а затем обновления, в многопоточной среде приводит к проблемам взаимоблокировки.

Я столкнулся со следующим сценарием при использовании NHibernate с SQL Server 2005.

У меня есть бизнес-процесс, который включает в себя следующие шаги:

  1. Начать транзакцию
  2. Создать сопоставленный объект nhibernate
  3. Сохранить сопоставленный объект nhibernate
  4. Выполнение других шагов бизнес-процесса
  5. Обновите сопоставленный объект nhibernate на шаге 2.
  6. Зафиксировать транзакцию

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

После расследования я обнаружил, что причина проблемы заключается в том, что nhibernate выдает оператор вставки и обновления для объекта, созданного на шаге 2 и обновленного на шаге 5. Из дальнейшего тестирования я понимаю, что оператор обновления блокирует всю таблицу, а не обновляются только строки, это приводит к взаимоблокировкам, когда другой поток пытается получить доступ к таблице для вставки или обновления.

Q1: Можно ли заставить nhibernate просто блокировать обновляемые строки, т. е. применять блокировку строк при выпуске обновления?

Пока я не нашел способа заставить nhibernate просто запустить один оператор вставки, а не вставить, а затем обновить оператор.

Q2: Кто-нибудь знает параметр конфигурации, чтобы изменить это поведение?

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

Мне было бы интересно узнать, сталкивался ли кто-нибудь с подобными проблемами.


person user85034    schedule 27.09.2010    source источник


Ответы (1)


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

Если это действительно невозможно, измените настройку изоляции транзакций в конфигурации, но это не рекомендуется.

person Community    schedule 27.09.2010