Шаблоны для реализации транзакций вне базы данных - PullRequest
9 голосов
/ 24 февраля 2009

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

Прежде чем я начну использовать свой собственный объектный механизм ACID, существуют ли общепринятые шаблоны для реализации семантики ACID на уровне объектов?

Еще лучше, есть ли какие-нибудь библиотеки, которые я могу использовать для платформы .NET?

Редактировать: Я знаю, что отправка электронной почты не может быть отменена, но не удается подключиться к SMTP-серверу, что приводит к завершению всей транзакции. Кроме того, я хотел бы, чтобы это было расширяемым для использования с будущими действиями.

Ответы [ 7 ]

5 голосов
/ 24 февраля 2009

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

Таким образом, если «транзакция» не удалась, механизм выдвинет объект команды, отменит команду, а затем уничтожит объект команды. Повторяйте, пока стек не опустеет. Стек очищается, если «транзакция» прошла успешно.

К сожалению, я не помню больше этого.

CSLA.NET реализует аналогичный стек отмены. Это единственный пример с кодом, который я могу придумать.

3 голосов
/ 24 февраля 2009

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

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

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

3 голосов
/ 24 февраля 2009

В Windows Workflow Foundation есть концепция компенсации (с использованием составного действия), когда семантика ACID может быть неуместной. Конечно, она также поддерживает транзакции ACID.

Хороший вопрос: зачем беспокоиться компенсация? Не одна большая кислота транзакция с автоматическим откатом так же хорошо? ACID транзакция наиболее целесообразно, когда происходят операции в той же базе данных или в пределах та же информационная система. Это также наиболее уместно, когда операции заканчиваются быстро. Когда разные компании и услуги участвуют, определяя процесс с точки зрения семантики ACID часто сложно. Чтобы это было изолированные и долговечные, вы должны держать все ресурсы разных компаний заблокирован на время выполнения задачи. Это часто неразумно, особенно если задача длинная. Для этого чтобы быть последовательным и атомарным, вам нужно специальный код компенсации.

1 голос
/ 18 августа 2009

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

Примером этого может быть простое создание учетной записи. Для этого вы хотите сохранить данные учетной записи в БД, а также отправить пользователю электронное письмо для активации - но вы хотите, чтобы они были в той же транзакции по очевидным причинам.

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

Итак, чтобы использовать JMS в этом сценарии - поместите код отправки JMS в транзакцию БД и попросите его присоединиться к этой транзакции. Вам гарантирована доставка сообщений. На другом конце есть что-то, потребляющее очередь отправки электронных писем. В случае сбоя при отправке электронной почты, лучший вариант - записать / подать предупреждение - JMS откатится и поместит сообщение обратно в очередь для последующего использования. то есть попытаться переслать письмо, как только вы, надеюсь, исправите проблему.

Критическая вещь - запись в БД непротиворечива, и электронная почта в конечном итоге отправляется.

1 голос
/ 24 февраля 2009

Поскольку вы не можете отменить отправку электронной почты, и написать файл относительно недорого, я просто выполнил бы эти действия в правильном порядке:

  1. Попробуйте записать файл / записать файл. В случае неудачи остановитесь, в противном случае продолжайте:
  2. Позвоните в веб-сервис. В случае неудачи удалите файл и остановитесь, в противном случае продолжайте:
  3. Отправка электронной почты - электронная почта в любом случае асинхронна, поэтому вы никогда не узнаете, была ли она отправлена ​​или нет, так как большинство почтовых серверов настроены на повторную попытку в течение нескольких дней, если возникает ошибка, и вы никогда не получите вернуть подтверждение, что электронное письмо прошло, даже если оно было успешным.
0 голосов
/ 18 августа 2009

Также недавно был выпущен экспериментальный проект STM .NET . Этот проект добавляет память транзакций в C #. Это фактически изменяет CLR для поддержки этого.

0 голосов
/ 24 февраля 2009

Две мысли:

...