NHibernate, ActiveRecord, блокировки базы данных транзакций и когда очищаются коммиты - PullRequest
2 голосов
/ 19 июня 2009

Это распространенный вопрос, но найденные до сих пор объяснения и наблюдаемое поведение несколько расходятся.

Нам нужна следующая стратегия nHibernate на нашем веб-сайте MVC:

  • A SessionScope для запроса (для отслеживания изменений)
  • ActiveRecord.TransactonScope, чтобы обернуть только наши вставки (для включения отката / фиксации пакета)
  • Выбирает быть за пределами транзакции (чтобы уменьшить степень блокировок)
  • Задержка сброса вставок (чтобы наши вставки / обновления выполнялись как UoW в конце сеанса)

В настоящее время мы:

  • Не получайте подразумеваемую транзакцию от SessionScope (с FlushAction Auto или Never)
  • Если мы используем ActiveRecord.TransactionScope, отсроченная очистка не происходит, и любые содержащиеся селекты также попадают в длительную транзакцию.

Мне интересно, если это потому, что у нас есть старая версия nHibernate (она была из транка очень близко к 2.0).

Мы просто не можем получить ожидаемое поведение nHibernate, и производительность отстой (используя NHProf и SqlProfiler для мониторинга блокировок БД).

1 Ответ

1 голос
/ 27 июня 2009

Вот что мы пробовали с тех пор:

  • Написал наш собственный TransactionScope (унаследованный от ITransactionScope), который:
    • Открывает ActiveRecord.TransactionScope в Commit , а не в ctor (задерживает транзакцию до тех пор, пока не потребуется)
    • Открывает 'SessionScope' в ctor, если ни один не доступен (в качестве защиты)
  • Преобразовал наши идентификаторы в Guid из идентичности
    • Это остановило автоматическую очистку insert / update вне транзакции (!)

Теперь у нас есть следующее поведение приложения:

  • Запрос от MVC
    • SELECT s, необходимых службам, запускаются, все за пределами транзакции
    • Repository.Add вызовы не попадают в базу данных, пока в наших контроллерах не будет вызван scope.Commit
    • Все INSERT с / UPDATE с происходят внутри транзакции как атомарная единица, без SELECT с.

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

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

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

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