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