Конфигурация JTA-транзакции в IBM Liberty - PullRequest
0 голосов
/ 17 января 2019

У меня есть MDB для запуска процесса (потока) в зависимости от некоторых условий. process/thread - это длительный процесс, поэтому мы не хотим удерживать поток, который вызвал MDB.

Таким образом, мы создаем новый поток и отправляем его исполнителю управляемого задания на свободу и иногда переходим в спящий режим, когда все не готово.

Поток читает записи из БД, отправляет их как сообщение другому MQ/JMS Queue, а затем записывает запись в БД.

Я хочу, чтобы записи MQ/JMS message и DB были частью transaction - оба должны успешно / неудачно работать вместе.

Как мне это сделать в IBM liberty environment.

Любые предложения / помощь приветствуется. Спасибо !!

Я пытался комментировать с @Transactional с REQUIRES_NEW, но не работает.

Обычно нам может потребоваться определить, что мы используем JTA transaction's, а затем аннотировать @Transactional.

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Если вы говорите о распределенной системе, то вы не можете сделать JMS-сообщение транснациональным, вы все равно отправите его. Вы должны использовать идемпотентность. А ты читай и пиши в БД должно быть в транскрипции.

Сделка: - читать из БД - отправить JMS - напишите в db

Даже если у вас происходит сбой в обслуживании и вы не выполняете транзакцию, в следующий раз вы снова отправите JMS, но служба получателя JSM будет реагировать на эту операцию идемпотентно (просто игнорируйте ее)

0 голосов
/ 22 января 2019

Когда мы создаем наши собственные потоки, контейнеры не позволяют нам управлять транзакциями, особенно когда мы вызываем commit в сеансе JMS.

Получилось так: Я вызываю асинхронный сессионный компонент из MDB. Контейнер сам управляет транзакцией этого сессионного компонента. Завершите публикацию сообщения и транзакций БД в другой сессионный компонент, который управляет своими собственными транзакциями (@TransactionManagement (value = TransactionManagementType.BEAN)).

В управляемом компонентом методе введите объект UserTransaction: @Ресурс UserTransaction userTransaction;

А затем управляйте транзакцией, используя: userTransaction.begin (); и userTransaction.commit (); и userTransaction.rollback ();

0 голосов
/ 17 января 2019

Задачи ManagedExecutorService, согласно спецификации, не выполняются в транзакции. Тем не менее, они имеют возможность начать новые транзакции. Вы можете сделать это следующим образом:

executor.submit(() -> {
    UserTransaction tx = InitialContext.doLookup("java:comp/UserTransaction");
    tx.begin();
    try {
        try (Connection con = dataSource.getConnection()) {
            ResultSet results = con.createStatement().executeQuery(...);
            ... process result set and send messages
            ... update database
        }
    } finally {
        tx.commit(); // or tx.rollback
    }
    return null;
});
...