2012-03-22 5 views
0

мы недавно наткнулись на поведение NHibernate, которое дало нам настоящую головную боль;).Изменения объекта-форварда за пределами транзакции

Давайте рассмотрим следующий пример:

declare x 
open transaction 
    create and persist object x 
commit transaction 

change object x 

open other transaction 
    do nothing 
close transaction 

Он ударил нас неожиданностью, что изменения, внесенные в «х» за пределами второй транзакции, где поручены к базе данных (хотя это поведение делает также смысл для меня, после того, как я подумал об этом). В нашей архитектуре это несколько проблема, поэтому мы привыкли к другому поведению в мире, из которого мы пришли;).

Теперь вопросы:

  1. Можно ли запретить изменения объекта за пределами сделки с NHibernate (например, бросить исключение)?
  2. Можно ли только зафиксировать изменения, которые фактически были сделаны внутри текущей транзакции?
  3. Есть ли какая-то совершенно другая вещь, которую мы могли бы сделать для обеспечения того, чтобы изменения в постоянных объектах выполнялись только в определенной области (с использованием директивы, класса, пространства имен и т. Д.)?

Спасибо за ваши thougths, BaSche

ответ

0

Я бы ответил на ваши вопросы, нет, нет и нет. Конечно, все возможно, например, вы можете сделать что-то уродливое с помощью INotifyPropertyChanged и выбросить исключение, если нет транзакции. Но NHibernate не предназначен для работы по вашему желанию.

NHibernate предназначен для того, чтобы ваши объекты не знали о персистентном слое, и в большинстве случаев это удается (с некоторыми заметными исключениями, такими как требование виртуального для ленивой загрузки). Операция NHibernate применяется для синхронизации состояния объекта с базой данных, а не с изменениями самих объектов. Кроме того, вы должны иметь возможность отката изменений объекта, если транзакция прервана, и это сложно.

0

Объект й не изменятся за пределы сделки, поскольку при открытии сеанса вы создаете транзакцию не явную. Когда вы вызывали transaction.Commit() или когда вы закрывали сеанс, это было сделано session.Flush(), и все ваши изменения были сохранены.

+0

Именно это и происходит. Мой вопрос: могу ли я изменить это поведение? Наша архитектура определяет ровно один уровень, который отвечает за транзакции. Это делается с помощью перехватчиков, которые открывают/фиксируют/откатывают транзакции перед обращением после вызова аннотированного метода (или класса). Теперь мы хотим, чтобы изменения в постоянных объектах были сделаны внутри транзакции. Таким образом, мы можем обеспечить, чтобы все изменения в нашей бизнес-модели были сделаны транзакционными, безопасными и «чистыми» в одном месте. – BaSche

+0

Вы не можете этого сделать. Вы не должны использовать неявную транзакцию: http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions. Но если вы хотите, чтобы этот объект не изменился, вы можете использовать session.Evict(), и он будет отсоединен от сеанса, и любые изменения не будут сохранены. – Anton

+0

Привет Антон, спасибо, что поделились ссылкой. Во всяком случае, мы не используем неявные транзакции, мы явно анотали некоторые ServiceInterfaces как транзакционные (как описано выше). – BaSche

Смежные вопросы