NHibernate - действительно ли ITransaction.Commit необходимо? - PullRequest
2 голосов
/ 13 июня 2010

Я только начал изучать NHibernate 2 дня назад, и я ищу метод CRUD, который я написал на основе учебника. Мой метод вставки:

        using (ISession session = Contexto.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Save(noticia);
            transaction.Commit();
            session.Close();
        }

Полный код "Contexto" находится здесь: http://codepaste.net/mrnoo5

Мой вопрос: действительно ли мне нужно использовать транзакция ITransaction = session.BeginTransaction () и транзакция.Commit (); ?

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

Если возможно, может кто-нибудь объяснить мне также цель Itransaction и метод Commit?

Спасибо

Ответы [ 3 ]

9 голосов
/ 13 июня 2010

Это правильный шаблон использования NHibernate:

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

Все это требуется для того, чтобы все работало должным образом (если вы не используете дополнительную инфраструктуру)

Закрытие сеанса или выполнение каких-либо действий с транзакцией, кроме фиксации, является избыточным, так как Dispose методы сеанса и транзакция заботятся об очистке, включая откат в случае возникновения ошибок.

Важно отметить, что выполнение что-либо с сеансом после исключения может привести к непредвиденному поведению, что является еще одной причиной ограничения явной обработки исключений внутри блока.

3 голосов
/ 13 июня 2010

Транзакция ITransaction = session.BeginTransaction () не требуется, как вы выяснили при тестировании.

Но представьте себе, что происходит, когда ваша сессия вызывает исключение? как бы вы вернули свои изменения в базу данных?

Следующая цитата из Nhib ...

Типичная транзакция должна использовать следующую идиому:

ISession sess = factory.OpenSession();
ITransaction tx; 
try 
{ 
    tx = sess.BeginTransaction(); //do some work ... 
    tx.Commit(); 
} 
catch (Exception e) 
{ 
    if (tx != null) 
    tx.Rollback(); 
    throw;
} 
finally 
{ 
    sess.Close(); 
}

Если ISession выдает исключение, транзакция должна быть откатана и сеанс отбрасывается. Внутреннее состояние ISession не может быть в соответствии с базой данных после возникновения исключения. NHibernate.ISessionFactory

1 голос
/ 13 июня 2010

Хорошо, вы вызываете Commit () для вашей транзакции, она сохраняет все изменения в базе данных.

Мне действительно нужно использовать транзакцию ITransaction = session.BeginTransaction () и транзакция.Commit ();?

да, считается хорошей практикой использовать транзакции для всего, даже простого чтения.

протестировано, запустите веб-приложение без этих двух строк, и я успешно вставил новые записи.

это потому, что сеанс будет фиксировать изменения, когда он будет расположен в конце оператора using.

В любом случае, вот как я бы исправил сохранение:

using (ISession session = Contexto.OpenSession())
{
    using (ITransaction transaction = session.BeginTransaction())
    {
        try
        {
            session.Save(noticia);
            transaction.Commit();
        }
        catch(HibernateException)
        {
            transaction.Rollback();
            throw;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...