Nhibernate: генерирует операторы вставки и обновления, в многопоточной среде приводит к проблемам взаимоблокировки - PullRequest
2 голосов
/ 27 сентября 2010

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

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

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

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

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

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

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

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

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

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

1 Ответ

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

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

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

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