2010-06-09 3 views
1

Как отменить изменения прикрепленного объекта в nhibernate? У нас есть подтверждение перед обновлением/сохранить (пример упрощен) ..Откат изменений в объекте, если он недействителен

var setting = Get("key") 
setting.Value = "helo" //for whatever reason, this particular 
         //setting cannot have its value saved to the database 
... 
Verify(setting);  //throws 
base.Update(setting); 

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

+0

Что вы подразумеваете под "любые изменения уже произошли"? –

+0

хе-хе, извините .. В зависимости от того, как настроена окружающая транзакция (и у меня нет 100% контроля над этим), сеанс привязан к базе данных w. новое значение («helo»), установленное. – hhravn

ответ

2

Это, скорее всего, , потому что окружающая сделка совершает, даже исключение вызывает. Или вы поймаете исключение позже и спрячете ошибку из окружающей транзакции. Обновление может выполняться NH всякий раз, когда он сбрасывает сеанс, например, перед выполнением запросов. Committing всегда синхронизирует состояние памяти с базой данных.

Обновление требуется только для экземпляров, которые еще не находятся в сеансе (но в базе данных). Все в сеансе синхронизируется с базой данных, любой момент времени, самое позднее при совершении.

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

Итак, что это значит для вашего кода?

  • Написать свой код, как если бы не было NHibernate или инерция. Это также улучшит ремонтопригодность и тестируемость.
  • Что вы делаете в памяти, является окончательным. У вас нет второго «магазина». Не делайте то, что вы не хотите делать.
  • Ваша память должна быть такой же последовательной, как и база данных. Ваша логика всегда основана на состоянии памяти (например, вычисления). Непоследовательная память нарушит согласованность приложения. Поэтому вы не должны фиксировать, когда у вас есть данные в памяти, которую вы не хотите в базе данных.
  • Commit все или ничего. Либо вы довольны своими изменениями, либо откатываете все.
  • Обработка исключений сложна. Не всегда легко решить, можете ли вы продолжить транзакцию.
  • Изменение состояния субъекта является ответственностью вашей бизнес-логики. NHibernate не будет «перезагружать» один экземпляр. (Существует Refresh, но он не будет работать здесь, и вы не должны его использовать). Поэтому, если вы хотите сбросить значение, вам нужно написать бизнес-логику, которая сбрасывает значение.
+0

Так что в принципе я должен либо отделять объекты, когда они находятся вне моего контроля (хуже), либо проверять, когда значение параметра установлено (лучше), чтобы быть уверенным, что они действительны? – hhravn

+0

Вы должны отменить всю транзакцию, если данные недействительны. Если вы хотите изменить значения только в том случае, если они действительны, вам необходимо проверить их до изменения объекта.Если вы хотите исправить одиночные значения после их установки на сущности, когда фиксируйте одиночные значения с помощью дополнительной логики. Не зависимо от (не) вызова Update и не зависит от выселения (отсоединения). Не зависеть от того, что база данных знает (возможно) исходное значение. Ваша бизнес-логика основана на объектах, она знает только одно значение, фактическое, после его изменения исходное значение теряется. –

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