NHibernate 3.0: TransactionScope и автоматическая очистка

В NHibernate 3.0 FlushMode.Auto не работает только при выполнении внешней транзакции (то есть без запуска транзакции NHibernate). Должно ли это?

using (TransactionScope scope = new TransactionScope()) 
{
    ISession session = sessionFactory.OpenSession();
    MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
    session.Save(entity);

    entity.Value = 30;
    session.SaveOrUpdate(entity);

    // This returns one entity, when it should return none
    var list = session.
               CreateQuery("from MappedEntity where Value = 20").
               List<MappedEntity>();
}

(Пример бесстыдно украденного из этого родственного вопроса)

В источнике NHibernate я вижу, что он проверяет, выполняется ли транзакция (в SessionImpl.AutoFlushIfRequired), но соответствующий метод (SessionImpl.TransactionInProgress) не учитывает окружающие транзакции - в отличие от своего двоюродного брата ConnectionManager.IsInActiveTransaction, который учитывает окружающие транзакции.

5 ответов

Решение

Хорошие новости. Благодаря Джеффу Стерну (который хорошо определил проблему) я обновил https://nhibernate.jira.com/browse/NH-3583 и благодаря персоналу NH уже есть исправление и запрос на удаление, поэтому в следующем выпуске 4.1. хх эта проблема будет исправлена.

Вы должны всегда использовать явную транзакцию NHibernate.

using (TransactionScope scope = new TransactionScope()) 
using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
    //Do work here
    transaction.Commit();
    scope.Complete();
}

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

Ответ, предоставленный Диего, не работает, если у вас есть база данных оракула. ( выпущенный вопрос). Сессия session.BeginTransaction не будет выполнена, поскольку соединение уже является частью транзакции.

Похоже, что мы должны написать некоторый код для решения этой проблемы в нашем приложении (WCF,NHibernate, Oracle), но кажется, что NHibernate должен предоставить "из коробки". Так что, если у кого-то есть хороший ответ, он будет очень признателен.

Я нашел ответ на это для оракула. Проверьте это здесь: проблема NHibernate TransactionScope с Oracle 11g

Для меня, я не знаю причину, но принудительное сбрасывание сессии до того, как сессия будет ликвидирована, похоже, сработало для меня. например, используя (сессия) { // делать свою работу

session.Flush(); }

Я проверил, что это работает с моей распределенной транзакцией, так как без этого я всегда получаю "транзакция прервана", когда TransactionScope удаляется.

Даже установить session.FlushMode для Commit не работает для меня.

Другие вопросы по тегам