Достижение NHibernate Вложенные Сделки Поведение - PullRequest
4 голосов
/ 19 апреля 2010

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

Я хочу открыть одну большую транзакцию, которая разбивается на маленькие транзакции.Представьте себе следующий сценарий:

  • TX1 открывает TX и вставляет запись человека;
  • TX2 открывает TX и обновляет имя этого человека до P2;
  • TX2 фиксирует;
  • TX3 открывает TX и обновляет имя этого человека до P3;
  • откаты TX3;
  • TX1 фиксирует;

Я бы хотелчтобы увидеть, как NH отправляет INSERT и TX2 UPDATE в базу данных, просто игнорируя, какой TX3, когда он был откатан.

Я пытался использовать FlushMode = Never и очищать сеанс только после соответствующих Begins / Commits /Откат был востребован, но NH всегда обновляет базу данных в соответствии с конечным состоянием объекта, независимо от фиксации и отката. Это нормально?Действительно ли NH игнорирует управление транзакциями при работе с FlushMode = Never?

Я также пытался использовать FlushMode = Commit и открывать вложенные транзакции, но я обнаружил, что, поскольку ADO.NET, вложенныйтранзакции, на самом деле, всегда являются одной и той же транзакцией.

Обратите внимание, что я не пытаюсь добиться поведения "все или ничего".Я ищу более безопасный способ работы. Есть ли способ сделать это (точки сохранения) с NH?

Заранее спасибо.

Filipe

Ответы [ 2 ]

7 голосов
/ 27 апреля 2010

Чтобы не оставлять этот вопрос открытым навсегда, я опубликую решение, которое мы приняли.

У нас есть единица работы, такая как контейнер, которая управляет поведением вложенных транзакций. В зависимости от того, какое лечение мы хотим, оно создает (или нет) новые сеансы. Например:

  • Продолжить в случае ошибки: если мы хотим, чтобы, даже если в случае ошибки транзакции зафиксированы другие, контейнер UoW использует разные сеансы для каждой «транзакции» и сбрасывает каждый tx в конце своей работы;
  • Откат при ошибке: если мы хотим, чтобы при откате сеанса (из-за ошибки или откате бизнеса) откатывались все остальные транзакции, контейнер UoW использует один и тот же сеанс для всех вложенных транзакций и откатывает всех в конец.

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

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

С уважением,

Филип

1 голос
/ 20 апреля 2010

NHibernate не поддерживает вложенные транзакции.Каждая ISession может иметь не более одной активной транзакции.Я не уверен, что вы пытаетесь выполнить, потому что ваш пример сценария не имеет смысла для меня.Передача транзакции 1 после вставки будет иметь тот же эффект.

...