При использовании NHibernate с SQL Server 2005 я столкнулся со следующим сценарием.
У меня есть бизнес-процесс, который включает следующие шаги:
- Начать транзакцию
- Создание сопоставленного объекта nhibernate
- Сохранить сопоставленный объект nhibernate
- Выполнение других шагов бизнес-процесса
- Обновление сопоставленного объекта nhibernate на шаге 2
- Подтвердить транзакцию
В однопоточной среде это работает нормально. Однако при запуске многопоточного нагрузочного теста, который выполняет один и тот же сценарий использования для отдельных объектов, я обнаружил, что столкнулся с множеством взаимоблокировок. Уровень изоляции транзакции оставлен на значении по умолчанию для фиксации чтения.
После расследования я обнаружил, что причина проблемы в том, что nhibernate выдает оператор вставки и обновления для сущности, созданной на шаге 2 и обновленной на шаге 5. Из дальнейшего тестирования я понимаю, что инструкция обновления блокирует всю таблица, а не только обновляемые строки, это приводит к взаимным блокировкам, когда другой поток пытается получить доступ к таблице для вставки или обновления.
В1: Можно ли заставить nhibernate просто заблокировать строки, которые он обновляет, т.е. применить блокировку строк при выпуске обновления?
Пока что я не нашел способа заставить nhibernate просто запустить один оператор вставки в отличие от оператора вставки и затем обновления.
Q2: Кто-нибудь знает вариант конфигурации для изменения этого поведения?
Мне удалось преодолеть проблему взаимоблокировок, возникающих в многопоточном нагрузочном тесте, включив изоляцию моментальных снимков в моей базе данных SQL Server и установив уровень изоляции транзакций в моментальный снимок.
Мне было бы интересно узнать, сталкивался ли кто-либо с подобными проблемами.