Как работают транзакции в nhibernate?

#c# #nhibernate #orm

#c# #nhibernate #orm

Вопрос:

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

Если я помещаю код в блок ‘using transaction’ и вызываю commit, это просто фиксирует изменения объекта, которые произошли в транзакции, или это фиксирует все изменения, которые произошли в сеансе с момента последней фиксации flush?

Ответ №1:

Цель транзакций — убедиться, что вы не зафиксируете сеанс с грязными данными или ошибкой в нем. Рассмотрим очень простой случай транзакции размещения заказа на книгу.

Вероятно, вы выполните следующие действия: a) Проверьте, существует ли книга на данный момент. б) Прочитайте данные о клиенте и посмотрите, есть ли у него что-нибудь в корзине покупок. c) Обновите количество книг d) Внесите запись для заказа

Теперь рассмотрим случай, когда при вводе заказа вы сталкиваетесь с ошибкой obs, и вы хотите, чтобы другие ваши изменения были откатаны, и именно тогда вы откатываете транзакцию.

Как вы это делаете? Ну, есть много способов. Один из способов для веб-приложений — отслеживать объект HTTP Error следующим образом:

 if(HttpContext.Current != null amp;amp; HttpContext.Current.Error != null)
transaction.Rollback();
  

В идеале вы не должны нарушать свой шаблон единицы работы, используя явные блоки транзакций. Старайтесь избегать этого, насколько это возможно

Комментарии:

1. Я в замешательстве, в этой статье говорится, что я должен использовать явные транзакции для всего, но вы говорите, что их использование нарушает шаблон «единица работы». nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

2. Я полагаю, он имеет в виду, что транзакции не должны использоваться непосредственно внутри методов сервиса / репозитория. Лучшим способом было бы создать ActionFilter или HTTP-модуль, который запускает транзакцию и фиксирует / откатывает ее в зависимости от того, было ли исключение.

3. В первом комментарии Мэтью говорится, что даже если вы явно не задаете транзакции, nhibernate все равно отправляет все это как транзакцию. Чем это отличается от явной настройки в HttpModule?

Ответ №2:

Если вы не используете транзакции, то в любое время, когда NHibernate отправляет пакет, это само по себе будет транзакцией. Я не уверен, что сессия.Flush() использует пакет или нет. Давайте предположим, что это так. Ваш первый вызов сеанса.Flush() приведет к транзакции. Предположим, что ваш второй вызов flush приводит к ошибке. Изменения после первого сброса останутся в базе данных.

Если, с другой стороны, вы используете явную транзакцию, вы можете вызывать flush миллион раз, но если вы откатите транзакцию (возможно, потому, что миллионная и одна промывка вызвали ошибки), то все промывки будут откатаны.

Надеюсь, это имеет смысл.

Комментарии:

1. Что мне все еще трудно понять, так это отслеживание объектов. Как явные транзакции влияют на глобальное отслеживание объектов? Допустим, постоянный объект изменяется (теперь грязный) вне явной транзакции, но я еще не фиксирую. Далее следует явная транзакция, которая выполняет несколько запросов, а затем фиксирует. Будут ли изменения в объекте вне явной транзакции также зафиксированы? Это то, что меня смущает.