Проблема транзакции NHibernate с несколькими сессиями - PullRequest
0 голосов
/ 02 ноября 2010

Я настроил NHibernate для запуска в службе Windows с MS Sql Server 2008. Я использую обычный TransactionScope, чтобы убедиться, что операция является атомарной. NHibernate настроен на создание фабрики сеансов для каждой сборки.

Я хочу записать изменения в объекты из 3 разных сборок. Все работает нормально, когда я работаю с одной или двумя сборками одновременно, но когда я добавляю чтение из третьей сборки, я сталкиваюсь с проблемами.

т.е. Чтение / запись в и из объектов в двух сборках работает нормально, добавление объектов из сборки создает проблемы. Однако чтение из третьей сборки без работы с объектами из двух других сборок также работает нормально. У меня такое ощущение, что сессии создают проблемы друг для друга.

Мой код такой:

using (var scope = new TransactionScope())
{
//Read object 1
//Do changes to object 2
//Do changes to object 3
scope.Complete();
}

Когда я пытаюсь завершить свою область транзакции (через scope.Complete ()), я получаю следующее сообщение об ошибке:

System.Data.SqlClient.SqlException: Microsoft Distributed Transaction Coordinator (MS DTC) has stopped this transaction.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment) 
System.Transactions.TransactionAbortedException: The transaction has aborted.
at System.Transactions.TransactionStatePromotedAborted.PromotedTransactionOutcome(InternalTransaction tx)
at System.Transactions.TransactionStatePromotedEnded.EndCommit(InternalTransaction tx)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()

Есть мысли?

1 Ответ

0 голосов
/ 03 ноября 2010

Сначала убедитесь, что вы правильно используете nHibernate и TransactionScope.Вот как это должно быть сделано (взято из Предотвращение утечек соединений с помощью NHibernate And TransactionScope ):

        using (var scope = new TransactionScope(TransactionScopeOption.Required))
        {
            using (var session = sessionFactory.OpenSession())
            using (var transaction = session.BeginTransaction())
            {
                // do what you need to do with the session
                transaction.Commit();
            }
            scope.Complete();
        }

Ошибка, которую вы получаете, является распространенной, если «повторное использование» сеансов между несколькими транзакциями,Я обнаружил, что это болезненный мир, поскольку распределенные транзакции фиксируются и откатываются в фоновых потоках, поэтому вы не можете знать, когда сможете их повторно использовать.Также код nHibernate не является потокобезопасным.Поэтому я предлагаю никогда не повторять сеансы , всегда уничтожать их согласно приведенному выше коду.

...