Отсутствует поддержка окружающих транзакций в nhibernate? - PullRequest
1 голос
/ 17 января 2010

Я знаю, что NHibernate поддерживает окружающие транзакции, потому что сеансы NHibernate включаются в окружающие транзакции, находясь внутри области транзакции.Однако есть некоторые странности, рассмотрим следующий тест:

[Test]
public void Transaction_RollsBackTransactionInsideOfAmbientTransaction_AmbientTransactionAborted()
{
    // arrange
    ISessionFactory sessionFactory = SessionFactoryOneTimeInitializer.GetTestSessionFactory();
    ISession session = sessionFactory.OpenSession();
    SessionFactoryOneTimeInitializer.CreateDataBaseSchemaIfRequiredByConfiguration(session);

    using (new TransactionScope())
    {
        using (ITransaction transaction = session.BeginTransaction())
        {
            // act
            transaction.Rollback();
        }

        // assert
        Assert.AreEqual(TransactionStatus.Aborted, Transaction.Current.TransactionInformation.Status); 
    }
}

Этот тест не пройден.Как NHibernate будет гарантировать, что окружающая транзакция не сохранится в базе данных?

1 Ответ

1 голос
/ 02 февраля 2010

Я достаточно хорошо знаю, как Hibernate работает с JTA в мире Java, но я не эксперт по .NET. Ваш вопрос, тем не менее, привлек мое внимание.

В Java вам необходимо настроить Hibernate с транзакцией JDBC или JTA. В этом случае объект Transaction, возвращаемый Hibernate, переносит транзакцию, связанную с одним подключением к базе данных (JDBC), или глобальную транзакцию, локальную для потока. Глобальный контекст локальной потоковой транзакции может быть признан недействительным с помощью UserTransaction#setRollbackOnly, что гарантирует, что он никогда не завершится успешно. Однако предпочтительно не управлять транзакциями через Hibernate, а использовать только объект UserTransaction, предоставленный JTA.

Это похоже на то же самое в NHibernate, и есть две фабрики транзакций. Один для распределенных транзакций и один для локальных транзакций . Но оба возвращают AdoTransaction:

public ITransaction CreateTransaction(ISessionImplementor session)
{
    return new AdoTransaction(session);
}

Похоже, что это не соответствует в случае распределенных / окружающих транзакций. Я не понимаю, как rollback будет работать в этом случае, учитывая, что глобальный контекст транзакции не может быть недействительным в .NET (насколько я понимаю), и AdoTransaction, по-видимому, представляет транзакцию при подключении к базе данных.

Так что я чувствую, что ответ на ваш вопрос "не будет", что объясняет, что ваш тест не пройден. Это означает, что вы не должны управлять транзакциями через NHiberate, если вы используете окружающие транзакции. Также как это не рекомендуется для Hibernate и JTA.

EDIT

См. Также этот вопрос: Как TransactionScope откатывает транзакции?

...