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