Транзакции с несколькими ресурсами (база данных и JMS-брокер) - PullRequest
0 голосов
/ 27 сентября 2019

У меня есть приложение, в которое мы вставляем базу данных и публикуем событие в ActiveMQ.

У меня проблемы с транзакцией.Поясню вопрос на код ниже:

@Transactional(rollbackFor = Exception.class)
public class ProcessInvoice {

    public boolean insertInvoice(Object obj){

        /* Some processing logic here */

        /* DB Insert */
        insert(obj);

        /* Some processing logic here again */

        /* Send event to Queue 1 */
        sendEvent(obj);

        /* Send event to Queue 2 */
        sendEvent(obj);

        return true;
    }
}

Класс помечается @Transactional, в insertInvoice метод, который я делаю некоторую обработку, вставив в БД, и отправка мероприятия в две очереди.

1009 * с выше кода я столкнулся с двумя проблемами:.
  1. Если очередь идет медленно, то я столкнулся проблемы с производительностью, как процесс занимает много времени в sendEvent метод

Как бороться с этимвопрос

Ответы [ 2 ]

0 голосов
/ 27 сентября 2019

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

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

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

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

0 голосов
/ 27 сентября 2019

У меня есть несколько вопросов относительно вашей проблемы:

  • Если метод sendEvent (Object o) является настолько дорогим (в зависимости от того, что вы говорите) с точки зрения производительности, почему вы считаете его вызовомдважды (очевидно, для обработки одного и того же объекта)?

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

  • Когда я думаю о транзакциях, первое, что приходит мне в голову, - это синхронные операции.,Вы хотите выполнять эти операции асинхронно или синхронно?Например, вы хотите подождать, пока счет-фактура будет вставлена ​​в БД для отправки сразу после сообщения в очередь1 и очередь2?

Возможно, вам следует сделать это асинхронно.Если вы этого не сделаете или не можете, возможно, вы могли бы выбрать «оптимистическую» стратегию, при которой вы сначала отправляете сообщение в Queue1 и Queue2, а затем, пока вы обрабатываете эти сообщения на стороне брокера, вы выполняете вставку счета-фактуры.в БД.Если база данных имеет высокую доступность, в большинстве случаев вставка будет успешной, поэтому вам не придется ждать, пока она будет сохранена, чтобы отправить сообщения в очереди 1 и 2. В случае, если вставка не удалась (что было бы очень маловероятно)Вы можете отправить второе сообщение, чтобы отменить эти изменения на стороне брокера.В случае, если из-за вашей бизнес-логики этот процесс отмены не является тривиальным, эта альтернатива может вам не подойти.

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

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

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

...