0

Я использую NHibernate 3. Мое приложение отлично работает при работе с SQL Server 2008, но имеет прерывистые ошибки в SQL 2000 (мы соответствующим образом изменили диалоги NH). Все ошибки связаны с компонентом MDTC (распределенная транзакция). Обычно чтение работает нормально, но код взрывается во время сохранения/обновления, но не всегда с той же ошибкой. Мы часто видели: «Распределенная транзакция завершена. Либо закрепите этот сеанс в новой транзакции, либо в транзакции NULL. '.Почему в NHibernate IPreUpdateEventListener/IPreInsertEventListener не было активной транзакции?

Я изучаю коренные причины этого и добавил некоторые записи. У меня есть перехватчики IPreUpdateEventListener и IPreInsertEventListener, поэтому я вхожу туда, а также в свой репозиторий. То, что я нахожу, заключается в том, что к тому моменту, когда я добираюсь до моего слушателя, на текущем сеансе транзакций нет.

Вот мой репозиторий код:

public virtual void Save(object entity) 
{ 
    logger.DebugFormat("Opening transaction to save entity type {0}.", entity.GetType().Name); 

    using (var t = new TransactionScope()) 
    { 
     GetSession().SaveOrUpdate(entity); 
     logger.DebugFormat("Committing transaction."); 
     t.Complete(); 
    } 
} 

И вот мой код события Слушатель:

logger.DebugFormat("Save/Insert entity. Transaction.Active = {0}", 
    persister.Factory.GetCurrentSession().Transaction != null 
    ? persister.Factory.GetCurrentSession().Transaction.IsActive.ToString() 
    : "no transaction"); 

А вот выход журнала:

2011-01-14 17:23:13,549 [9] DEBUG BaseRepository`1.Save - Opening transaction to save entity type XXXXXXX. 
2011-01-14 17:23:13,566 [9] DEBUG BaseRepository`1.Save - Committing transaction. 
2011-01-14 17:23:13,598 [9] DEBUG AuditEventListener.Audit - Save/Insert entity. Transaction.Active = False 

Вы можете увидеть что-нибудь неправильно с этим? Почему в предварительной вставке нет транзакции? Кто-нибудь знает что-то особенное, что мне нужно сделать для Sql Server 2000 (MSDTC включен)?

Обратите внимание, что окружающая среда 2008 моя локальная машина под управлением Windows 7 и Sql сервер Server 2000 является Server 2003.

ответ

3

TransactionScope делает не создать транзакцию NHibernate.

Вы должны создать его явно, используя session.BeginTransaction(). Он будет автоматически зачислен в распределенную транзакцию (не забудьте до Commit() до завершения)

+1

Спасибо. Это я устал и не видел этого. Я переключился на транзакции NH, и у нас была аналогичная, но связанная с этим ошибка, и Transaction.Active все еще была ложной в прослушивателе событий, хотя мы сделали сеанс.BeginTransaction(). Это происходит только тогда, когда приложение находится на другой машине для сервера Sql, поэтому я предполагаю, что это связано с сетью/разрешением. –