NHibernate, ActiveRecord, блокировки базы данных транзакций и когда очищаются коммиты
Это общий вопрос, но объяснения, найденные до сих пор, и наблюдаемое поведение находятся в некотором роде.
Нам нужна следующая стратегия nHibernate на нашем веб-сайте MVC:
SessionScope
для запроса (для отслеживания изменений)ActiveRecord.TransactonScope
обернуть только наши вставки (чтобы включить откат / фиксацию пакета)- Выбирает быть вне транзакции (чтобы уменьшить степень блокировок)
- Задержка сброса вставок (так что наши вставки / обновления происходят как UoW в конце сеанса)
Сейчас на данный момент мы:
- Не получайте подразумеваемую транзакцию от
SessionScope
(с FlushAction Auto или Never) - Если мы используем
ActiveRecord.TransactionScope
нет отложенного сброса, и любые содержащиеся селекты также попадают в длительную транзакцию.
Мне интересно, если это потому, что у нас есть старая версия nHibernate (она была от ствола очень близко к 2.0).
Мы просто не можем получить ожидаемое поведение nHibernate и отстой производительности (используя NHProf и SqlProfiler для мониторинга блокировок БД).
1 ответ
Вот что мы попробовали с тех пор:
- Написал наш собственный TransactionScope (унаследованный от ITransactionScope), который:
- Открывает
ActiveRecord.TransactionScope
на коммите, а не вctor
(задерживает транзакцию, пока не потребуется) - Открывает SessionScope в
ctor
если ни один не доступен (в качестве охраны)
- Открывает
- Преобразовал наши идентификаторы в Guid из идентичности
- Это остановило автоматическую очистку
insert
/update
вне транзакции (!)
- Это остановило автоматическую очистку
Теперь у нас есть следующее поведение приложения:
- Запрос от MVC
SELECT
s, необходимые для служб, увольняются, все за пределами транзакцииRepository.Add
звонки не попадают в БД, покаscope.Commit
называется в наших контроллерах- Все
INSERT
с /UPDATE
возникают внутри транзакции как атомарная единица, безSELECT
содержится.
... но почему-то сейчас nHProf!= SqlProfiler (select
Похоже, что это происходит в БД до того, как об этом сообщит nHProf.
ПРИМЕЧАНИЕ Прежде чем я разгорячусь, я осознаю проблемы здесь и знаю, что SELECT не включены в транзакцию. Это дизайн. Некоторые из наших операций будут содержать SELECT (теперь у нас есть пара наших собственных TransactionScope
реализации) в сериализованных транзакциях. Подавляющему большинству нашего кода не нужны самые свежие данные, и мы сериализовали рабочие нагрузки с отдельными операторами.
ТАКЖЕ, если кто-нибудь знает, как обновить столбец идентификации (не PK) послеinsert
без необходимости вручную обновлять объект, в частности, используя разметку ActiveRecord (я думаю, что это возможно в файлах отображения nHibernate с использованием атрибута "Генерируемый"), пожалуйста, дайте мне знать!!