Атомарные операции на нескольких внешних системах без транзакций - PullRequest
9 голосов
/ 10 июня 2010

Допустим, у вас есть приложение, соединяющее 3 разные внешние системы.Вам нужно что-то обновить во всех 3. В случае сбоя необходимо откатить операции.Это несложно реализовать, но, скажем, операция 3 завершается неудачно, а при откате происходит откат операции 1!Теперь первая внешняя система находится в недопустимом состоянии ...

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

Есть ли хорошие способы обработки таких случаев?

РЕДАКТИРОВАТЬ: Некоторые детали приложения ..

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

Я думал об изменении приложения для использования шаблона «Команда и единица работы»

Ответы [ 4 ]

1 голос
/ 13 июня 2010

Двухфазная фиксация ( 2PC ) может быть подходящей здесь.

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

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

1 голос
/ 13 июня 2010

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

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

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

0 голосов
/ 13 июня 2010

Ответ странного мышления хороший, но ограниченный, потому что на самом деле надежно сделать 2PC очень трудно.Это было известно в сообществе распределенных вычислений довольно давно, хотя многие люди стараются просто игнорировать это.

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

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

0 голосов
/ 10 июня 2010

В зависимости от размера приложения (один пользователь или предприятие), закрытие приложения может быть плохой идеей.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...