Nhibernate с ошибкой TransactionScope - фаза подготовки транзакции DTC не выполнена - Обновление до Nhibernate 3.0 - PullRequest
5 голосов
/ 08 февраля 2011

Я получаю следующее исключение при использовании операций Nhibernate и ADO.Net внутри транзакции Scope.Eg. Это было хорошо с Nhibernate 2.1, но теперь обновлен до 3.0, который выдает ошибку.

using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
        GetmemberId(); --> NHibernate Call
        Update(); ADO Call OracleDB
}

Так как это действует как окружающая транзакция, Nhibernate пытается расположить транзакцию незадолго до завершения внешней транзакции. Исправьте меня, если я ошибаюсь, есть ли какое-либо решение, потому что помогите мне, но когда я перемещаю вызов Nhibernate за пределы TransactionScope, все работает нормально , Пример, который я привел, это первый пример, мины связаны с более сложным, так как я держу и вызовы внутри TransactionScope, и ошибка, которую я получаю, выглядит следующим образом:

ОШИБКА 13 NHibernate.Impl.AbstractSessionImpl - Подготовка транзакции DTC фаза не выполнена System.ObjectDisposedException: невозможно получить доступ к удаленному объект. Название объекта: «Транзакция». в System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) в System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) в System.Transactions.TransactionScope.PushScope ()
в System.Transactions.TransactionScope.Initialize (Транзакция actionToUse, TimeSpan scopeTimeout, логическое interopModeSpecified) at System.Transactions.TransactionScope..ctor (Транзакция actionToUse) в NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (PreparingEnlistment prepareEnlistment) 2011-02-08 13: 41: 46,033 ОШИБКА 13 NHibernate.Impl.AbstractSessionImpl - фаза подготовки транзакции DTC Ошибка System.ObjectDisposedException: не удается получить доступ к удаленному объект. Название объекта: «Транзакция». в System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) в System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) в System.Transactions.TransactionScope.PushScope ()
в System.Transactions.TransactionScope.Initialize (Транзакция actionToUse, TimeSpan scopeTimeout, логическое interopModeSpecified) at System.Transactions.TransactionScope..ctor (Транзакция actionToUse) в NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (PreparingEnlistment preparingEnlistment)

Ответы [ 2 ]

6 голосов
/ 07 марта 2012

Попробуйте

Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")

Или в конфиге nhibernate

<property name="transaction.factory_class">
NHibernate.Transaction.AdoNetTransactionFactory
</property>

У меня это сработало =)

1 голос
/ 07 мая 2015

Мы столкнулись с этой же ошибкой, и она была вызвана тем, как мы использовали сеансы и транзакции в нашем Web Api с NHibernate.

Мы должны использовать сеанс для запроса. (Это может быть веб-запрос или выполнение обработчика NServiceBus.) Когда запрос запускается, вы должны открыть сеанс и начать транзакцию.

Мы этого не делали. В наших репозиториях мы создали новый сеанс и транзакцию для каждого запроса базы данных. Это означало, что вместо одного сеанса / транзакции для запроса у нас их было много.

Основная причина ошибки для нас заключалась в том, что мы загружали сущность (объект модели домена) за один сеанс, модифицировали ее и сохраняли в другом сеансе. К тому времени, когда NHibernate выполнил вызов обновления, сеанс / транзакция загрузки уже были зафиксированы, очищены и закрыты.

Решением было вытащить наше создание сеанса / транзакции из репозиториев и на уровень контроллера (выполнимо с помощью HttpModule для вызовов REST и / или с аспектно-ориентированным программированием с использованием внедрения зависимостей). Эта одна сессия / транзакция затем живет в течение времени жизни вызова REST или выполнения обработчика NServiceBus и используется для всего доступа к базе данных во время этого вызова. Когда этот вызов заканчивается, он будет зафиксирован или отменен в зависимости от ситуации.

Ответ, приведенный выше при настройке свойства config, просто отключает DTC и возвращает к старому способу выполнения транзакций NHibernate. Это может решить проблему для вас, если вам никогда не придется масштабировать свой Web Api до нескольких экземпляров, но если вы это сделаете, это вызовет у вас проблемы.

...