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
    • SELECTs, необходимые для служб, увольняются, все за пределами транзакции
    • Repository.Add звонки не попадают в БД, пока scope.Commit называется в наших контроллерах
    • Все INSERTс / UPDATEвозникают внутри транзакции как атомарная единица, без SELECTсодержится.

... но почему-то сейчас nHProf!= SqlProfiler (selectПохоже, что это происходит в БД до того, как об этом сообщит nHProf.

ПРИМЕЧАНИЕ Прежде чем я разгорячусь, я осознаю проблемы здесь и знаю, что SELECT не включены в транзакцию. Это дизайн. Некоторые из наших операций будут содержать SELECT (теперь у нас есть пара наших собственных TransactionScope реализации) в сериализованных транзакциях. Подавляющему большинству нашего кода не нужны самые свежие данные, и мы сериализовали рабочие нагрузки с отдельными операторами.

ТАКЖЕ, если кто-нибудь знает, как обновить столбец идентификации (не PK) послеinsert без необходимости вручную обновлять объект, в частности, используя разметку ActiveRecord (я думаю, что это возможно в файлах отображения nHibernate с использованием атрибута "Генерируемый"), пожалуйста, дайте мне знать!!

Другие вопросы по тегам