Фон
У меня есть Клиентское приложение Spring, которое настраивает сервис к двум серверам с помощью RMI. В клиент я сохраняю объект к (легкой) базе данных и выполняю rmi вызовы к двум серверам с деталями объекта. Я использую Spring 3.0.2 на серверах, и клиент является простым сайтом Spring-mvc.
Требования
Мое требование - то, что, если какой-либо из вызовов rmi перестал работать к серверам, которые откатывает целая транзакция, который является объектом, не сохраняется на клиенте и если любой, вызов rmi был успешен, который это также откатывает.
Я относительно плохо знаком с Распределенными транзакциями, но я предполагаю, что хочу XA как транзакция с помощью вызовов RMI.
Я действительно находил хорошую ссылку на предмет здесь, но он не упоминает шаблон для при вызове двух вызовов удаленного метода к различным серверам. Я хотел бы услышать больше о предмете с точки зрения рекомендуемого чтения и также любых указателей о том, как достигнуть этой пружины использования. Действительно ли использование является менеджером транзакций для этого возможного?
Спасибо.
Вот как теоретически можно разрешить эту ситуацию. Для начала вам нужно иметь несколько распределенных менеджеров транзакций JTA на каждом узле. Один действует как хозяин, другой - как рабы. Мастер координирует фиксацию / откат распределенной транзакции на подчиненных устройствах. Существуют автономные реализации JTA, например JOTM .
Стандартный RMI не поддерживает распространение контекстной информации, такой как идентификатор транзакции операции. Но я думаю, что у RMI есть зацепки, так что его можно расширить для поддержки этого. Вы можете посмотреть Кэрол .
Вам нужно будет использовать XAResource , чтобы обернуть участников транзакции, чтобы их можно было включить в распределенную транзакцию. Мастер должен будет отправить сообщения фиксации / отката подчиненным, которые должны будут использовать XATerminator , чтобы действовать соответствующим образом.
Спецификация JTA - это только диспетчер распределенных транзакций , регистрация операций в журнале транзакций должна выполняться серверами. Библиотека существует для управления журналом транзакций, например HOWL .
Я не думаю, что Spring можно использовать - даже с диспетчером распределенных транзакций - для этого легко. Однажды я попытался использовать RMI с распределенной транзакцией, управляемой с автономного клиента и нескольких ведомых устройств. Вот сообщение в блоге об этом. Это было довольно сложно.
Вы можете получить все это бесплатно, если используете сервер приложений Java EE с IIOP. IIOP поддерживает распределенное распространение транзакций.Клиент может быть контейнером клиента приложения , и вы можете управлять транзакциями с помощью UserTransaction . На самом деле это один из тех редких случаев, когда я считаю, что использование сервера приложений действительно оправдано.
Но при этом распределенные транзакции - это сложные вещи, которые могут привести к эвристическим сбоям, тайм-ауту в случае выхода из строя одного узла и сложным процедурам восстановления.
Мой последний совет был бы таким: постарайтесь найти дизайн, который не включает распределенную транзакцию, если это возможно. Это сделает ваше лайк намного проще.
Вы можете почерпнуть вдохновение в механизме компенсации BPEL . Возможно, существуют другие подходы к проектированию для обработки ошибок и обеспечения устойчивости, которые могут избежать использования распределенных транзакций.
Насколько мне известно, Spring как таковой не управляет распределенными транзакциями. Он может использовать JtaTransactionManager
, который, в свою очередь, делегирует полномочия координатору транзакций сервера Java EE. Насколько я понимаю, такие транзакции доступны только для источников данных, зарегистрированных в контейнере приложения.
Вы можете попробовать написать свою собственную реализацию XAResource
(не уверен, что это лучший способ, но все же) и зарегистрировать ее в контейнере приложения, но Spring вам в этом особо не поможет.