2008-09-18 3 views
4

Сценарий этотдвухфазного принятия/Shared транзакции

У нас есть два приложения А и В, и которые работают в отдельной базе данных (Oracle 9i) сделки

Применение A - вставляет некоторые данные в базу данных , затем вызывает Application B Приложение B - вставляет некоторые данные в базу данных, связанные (через внешние ключи) с данными A. Возвращает «ID» в приложение A Приложение A - использует идентификатор для ввода дополнительных данных, включая идентификатор от B

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

Как вы подходите к этой проблеме с минимальным рефакторингом кода. Наверняка, это такая распространенная проблема в мире SOA?

------ Обновление --------

Я не смог найти что-нибудь в Oracle 9i, однако Oracle 11g обеспечивает DBMS_XA, который делает именно то, что я был после.

+1

Я не думаю, что теги актуальны. java, perl, jboss даже не упоминаются в вопросе, и проблема не связана с оракулом. – 2008-09-30 15:45:31

ответ

11

У вас есть три варианта:

  1. перепроектировать приложение, так что вы не имеете два различных процесса (как с подключением баз данных) записи в базу данных и раскатать его в одном приложении.

  2. Создание приложения C, который обрабатывает все транзакции базы данных для A и B.

  3. Ролла своей собственные две фазы фиксации. В качестве координатора выступает приложение C. C сигналы A и B, чтобы спросить, готовы ли они совершить. A и B выполняют свою обработку и отвечают на C с ответом «готов» или «сбой» (обратите внимание, что на C должен быть тайм-аут, чтобы избежать бесконечного ожидания, если один процесс зависает или умирает). Если оба ответа готовы, то C сообщает им о фиксации. В противном случае он отправляет сигнал отката.

Обратите внимание, что вы можете столкнуться с проблемами с вариантом 3, если приложение А полагаться на внешние ключи из приложения B (которые вы не государство, так что это не может быть проблемой). Согласованность чтения Oracle, вероятно, помешает этому разрешить, так как транзакция приложения A начнется до приложения B. Просто предупреждение.

+0

Я боялся, что так будет, надеялся, что кто-то знает что-то, чего я не сделал. Подождите, чтобы увидеть, есть ли у кого-нибудь что-нибудь волшебное, если не ответит. – 2008-09-18 02:26:23

2

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

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

0
App_A =={0}=>    database # App_A stores information for App_B 
App_A ------> App_B     # App_A starts App_B 
       App_B <={0}== database # App_B retrieves the information 
       App_B =={1}=> database # App_B stores more informaion 
App_A <={2}== App_B     # App_B returns 'ID' to App_A 
App_A ={2,3}>    database # App_A stores 'ID' and additional data 

Это только меня или это, кажется, как Application B является по существу только подпрограммой А. Я имею в виду приложение B не делать ничего до тех пор, пока его спрашивает, и приложение А пока ничего не делает, пока B возвращает идентификатор. Это означает, что нет смысла иметь их в разных приложениях или даже отдельных потоках.

+2

Приложение A вставляет данные в базу данных, необходимые B, затем вставляет больше данных, возвращаемых из B. – 2008-09-18 03:46:29

+0

Я знаю, как это работает на самом деле, я просто пытался объяснить это более абстрактным образом. – 2008-09-30 15:29:26

1

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

Это может быть объединено с двухуровневым (предлагается система управления движением Zathrus) - потому что это действительно не понадобилось бы для решения neonski использования таблицы или таблиц «альбомной». Недостатком этого является то, что вы должны будете, чтобы ваши procs/logic проконсультировались с основной таблицей из рабочей области или рабочей области из основной таблицы, или, возможно, сохраните свой флаг в главной таблице и установите его обратно, когда вы передаете данные в основной стол.

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

3

Несколько предложений:

  • Использование Compensating transactions. В принципе, вы можете отменить транзакцию, которую вы делали ранее. Трудная часть - выяснение, какие транзакции для отката.

  • Зафиксировать данные приложений A и B в базе данных с помощью флага, указывающего, что он является временным. Затем, после того, как все будет проверено, измените флаг, чтобы указать, что данные являются окончательными. В течение ночи запустите пакетное задание, чтобы очистить данные, которые не были доработаны.

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