Проблема NHibernate TransactionScope с Oracle 11g

Следующий фрагмент кода прекрасно работает с SQL Server 2008 (SP1), но с Oracle 11g при вызове session.BeginTransaction () выдает исключение с сообщением «Соединение уже является частью локальной или распределенной транзакции» (трассировка стека показана ниже) , Использование «NHibernate.Driver.OracleDataClientDriver».

Кто-нибудь еще сталкивался с этим?

using (var scope = new TransactionScope())
{
   using (var session = sessionFactory.OpenSession())
   using (var transaction = session.BeginTransaction())
   {
      // do what you need to do with the session
      transaction.Commit();
    }
    scope.Complete();
}
     Exception at:    at NHibernate.Transaction.AdoTransaction.Begin(IsolationLevel isolationLevel)
           at NHibernate.Transaction.AdoTransaction.Begin()
           at NHibernate.AdoNet.ConnectionManager.BeginTransaction()
           at NHibernate.Impl.SessionImpl.BeginTransaction()
           at MetraTech.BusinessEntity.DataAccess.Persistence.StandardRepository.SaveInstances(List`1& dataObjects) in S:\MetraTech\BusinessEntity\DataAccess\Persistence\StandardRepository.cs:line 3103

        Inner error message was: Connection is already part of a local or a distributed transaction
        Inner exception at:    at Oracle.DataAccess.Client.OracleConnection.BeginTransaction(IsolationLevel isolationLevel)
           at Oracle.DataAccess.Client.OracleConnection.BeginDbTransaction(IsolationLevel isolationLevel)
           at System.Data.Common.DbConnection.System.Data.IDbConnection.BeginTransaction()
           at NHibernate.Transaction.AdoTransaction.Begin(IsolationLevel isolationLevel)

Ответы на вопрос(4)

NHibernate FlushMode Auto не очищается перед поиском

Похоже, что nhibernate (v3.1 с оракулом и 11g db w / opd.net v2.112.1.2) требует своих собственных транзакций, чтобы избежать проблемы сброса, но я не смог заставить область транзакции работать с nhibernate сделки.

Я не могу заставить его работать :( это может быть дефект в nhibernate или odp.net, не уверен ...

нашел такую ​​же проблему здесь:NHibernate 3.0: TransactionScope и автоматическая очистка

ИСПРАВЛЕНО: найдено решение! поставив "enlist = dynamic;" в мою строку соединения оракула проблема была решена. Мне удалось использовать как транзакцию nhibernate (чтобы исправить проблему сброса), так и объем транзакции, например, так:

        ISessionFactory sessionFactory = CreateSessionFactory();

        using (TransactionScope ts = new TransactionScope())
        {
            using (ISession session = sessionFactory.OpenSession())
            using (ITransaction tx = session.BeginTransaction())
            {
                //do stuff here

                tx.Commit();

            }
            ts.Complete();
        }

Я проверил свои файлы журналов и нашел это: 2011-06-27 14: 03: 59,852 [10] DEBUG NHibernate.Impl.AbstractSessionImpl - зачислен в транзакцию DTC: Сериализуемый

прежде чем какой-либо SQL был выполнен в соединении. Я проведу модульное тестирование, чтобы подтвердить правильность выполнения. Я не слишком уверен, что сериализуемый говорит мне, хотя

Из поваренной книги NHibernate

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

Мое мнение также заключается в том, что он должен работать вместе с TransactionScope, но это не так, ни в 3.3.x.x, ни в версии 4.0.0.400.

Приведенный выше рецепт может работать, но нужно проверить его с помощью вложенного TrancactionScope, с внутренним TransactionScope, для которого определен Transaction.Suppress (при использовании SQL) и т. Д ...

анзакции NHibernate с enlist = dynamic, похоже, не работает должным образом. Хорошо, данные передаются.

Но если вы опустите scope.Complete () или создадите исключение после tx.Commit (), данные все равно будут зафиксированы (для Oracle)! Однако по какой-то причине это работает для SQL-Server.

Транзакции NHibernate заботятся об автоматической очистке, но в конце они вызывают основную транзакцию ADO.NET. В то время как многие источники поощряют приведенную выше модель как лучшую практику для NHibernate для решенияавтоматическая промывкаИсточники, обсуждающие нативный ADO.NET, говорят об обратном: НЕ используйте TransactionScope и внутренние транзакции вместе, не для Oracle и не для SQL-Server. (Увидетьэтот вопрос а такжемой ответ)

Мой вывод: Не объединяйте транзакции TransactionScope и NHibernate. Чтобы использовать TransactionScope, пропустите транзакции NHibernate и обработайте сброс вручную (см. ТакжеNHibernate Flush doc).

почему вы делаете внутреннюю сессию.BeginTransaction - начиная с версии 2.1 GA NHibernate автоматически регистрируется в контекстах TransactionScope, поэтому больше нет причин делать свою собственную.

 Konstantin20 апр. 2012 г., 10:13
Может быть, чтобы заставить работать автозапуск NHibernate правильно

Ваш ответ на вопрос