Компоненты и транзакции, управляемые сообщениями

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

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

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

Каков наилучший способ справиться с этим сценарием? В настоящее время я использую Thread.sleep в Consumer, который работает; однако это кажется грязным ...

(Я не использую Spring)


person StuPointerException    schedule 23.02.2016    source источник
comment
является ли эта служба EJB и кто вызывает эту службу?   -  person Madhusudana Reddy Sunnapu    schedule 23.02.2016
comment
Это служба CDI (ApplicationScoped), и она будет вызываться из любой другой службы CDI. Транзакции - это DeltaSpike (поэтому, к сожалению, я не могу использовать функцию @Observes TransactionPhase... JavaEE).   -  person StuPointerException    schedule 23.02.2016
comment
если у вас есть поддержка XA, вы можете попробовать с XADatasource и XAConnectionFactory. Или, как предложил TT, вы можете поместить сообщение в очередь из класса, который вызывает вашу службу после возврата вызова службы.   -  person Madhusudana Reddy Sunnapu    schedule 23.02.2016


Ответы (2)


У вас может быть транзакция, которая делает обычные вещи, а также вставляет электронные письма в таблицу. Не отправляйте письма в транзакции.

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

person TT.    schedule 23.02.2016
comment
Я пытаюсь избежать запланированного задания. Знаете ли вы, где еще я могу подключиться к жизненному циклу транзакции, чтобы запустить это сообщение (в идеале оно должно быть прозрачным для вызывающего абонента)? Я думал об использовании событий JPA, но они внутри одной транзакции... - person StuPointerException; 23.02.2016
comment
@StuPointerException Отправить сообщение в очередь в конце транзакции. Потребитель будет запускать сообщение для отправки писем. Разве это не сработает? В этом случае процесс-потребитель не будет выполняться в транзакции. - person TT.; 23.02.2016
comment
Спасибо за помощь в этом, проблема, с которой я сталкиваюсь, заключается в том, чтобы узнать, когда Tx был зафиксирован, поскольку он уже запущен, когда вызывается метод службы. Это желательно, поскольку это означает, что сообщение электронной почты фактически откатывается, если вызывающий метод выдает исключение. - person StuPointerException; 23.02.2016
comment
@StuPointerException Ну, вам нужен контроль над транзакцией, если вы хотите правильно обработать это. Если вы не можете, вам нужно выяснить, как иметь строгий контроль над транзакцией, или запускать рассылку на другом уровне. Нет пути вокруг этого. - person TT.; 23.02.2016
comment
Спасибо за помощь! - person StuPointerException; 24.02.2016

Может быть, поможет сброс сразу после сохранения почты?

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

person Kevyn Meganck    schedule 23.02.2016
comment
Спасибо за предложение, однако я пытаюсь избежать сохранения записи электронной почты, если клиент выдает исключение. Я просто не могу подключиться к жизненному циклу транзакции, чтобы узнать, что станет с указанной транзакцией! - person StuPointerException; 23.02.2016