Как предотвратить повторную доставку сообщений от MQ Broker после успешной обработки внутренних доставок верблюда (транзитный верблюжий маршрут) - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь запустить маршрут transacted () с верблюдом (автономный процесс Java) с помощью JPATransactionManager - это пружинный PlatformTransactionManager (так как я хочу, чтобы маршрут верблюда выполнялся в одной транзакции с БД), но я не могу отменить повторную доставку из MQПосредник в случае сбоя транзакционного метода, даже если я использовал handled (true) в предложении onException вместе с моей собственной политикой повторной доставки (которая выполняется успешно).Я хочу, чтобы MQ повторно доставлялся только в случае сбоя службы.

Пробовал ниже, но он не работает:

  • Установка setTransacted (false) в конфигурации JMSComponent, чтобы предотвратить верблюдаjms для запуска является режимом transacted_session jms, но он не работает
  • doTry и doCatch исключение из транзакционного блока
  • доставок верблюдов с последующей обработкой (true).

    onException(Exception.class)
        .log("ERROR OCCURRED")
        .redeliveryPolicyRef("myRedeliveryPolicy")
        .handled(true)
        .to(getPostExceptionRoute());
    
    @Bean
    @Autowired
    public RedeliveryPolicy myRedeliveryPolicy() {
        RedeliveryPolicy myRedeliveryPolicy= new RedeliveryPolicy();
        myRedeliveryPolicy.setMaximumRedeliveries(2);
        myRedeliveryPolicy.setMaximumRedeliveryDelay(2000);
        return myRedeliveryPolicy;
    }
    
    @Bean
    @Autowired
    public JmsComponent jms(IJMSConnectionFactory cf) throws JMSException {
        JmsComponent jmsComponent = new JmsComponent();
        jmsComponent.setConfiguration(jmsConfig(cf));
        jmsComponent.setTransacted(false);
        return jmsComponent;
    }
    
    from("jms:queue:TestQueue?acknowledgementModeName=CLIENT_ACKNOWLEDGE")
        .unmarshal().json(JsonLibrary.Jackson, TestObject.class)
        .transacted()
        .processRef("myPersistInDBProcessor")
    
  • Я ожидаю, что верблюд попытается доставить согласно политике повторной доставки (работает), но MQ не должен выполнять повторную доставку.

  • Я ожидаю, что мой верблюжий маршрут будет выполняться в одной транзакции дБ.
  • Я ожидаю, что MQ-брокер выполнит повторную доставку только в случае сбоя моего java-сервиса в середине обработки, чтобы я не потерял сообщение.

Ответы [ 2 ]

0 голосов
/ 12 июня 2019

В соответствии с Руководством по транзакциям Apache Karaf должно делать doTry и doCatch, как ожидалось. Вероятно, проблема в вашем случае - исключение, вызывающее сценарий ошибки. Только проверенные исключения (без RuntimeException или его потомка) не помечают текущую транзакцию для отката.

0 голосов
/ 12 апреля 2019

Я ожидаю, что верблюд попытается доставить в соответствии с политикой повторной доставки (работает), но MQ не должен повторно доставлять

Когда MQ никогда не должен делать повторную доставку (потому что вы обрабатываете ошибки в Camel), вы должны удалить acknowledgementModeName=CLIENT_ACKNOWLEDGE или явно установить AUTO_ACKNOWLEDGE (значение по умолчанию).

Пока сообщение не подтверждено, оно с точки зрения брокера не доставляется. AUTO_ACKNOWLEDGE немедленно подтверждает сообщение после потребления, что имеет смысл, если вы никогда не хотите получать доставку.

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

РЕДАКТИРОВАТЬ из-за комментария с новой информацией

Если вы хотите получать MQ, но в большинстве случаев «переопределять» их с помощью Camel, вам нужно потреблять сообщения, обработанные .

Используйте локальных транзакций JMS-брокера , настроив свой компонент JMS следующим образом

jmsComponent.setLazyCreateTransactionManager(false);
jmsComponent.setTransacted(true);

Для транзакций этого типа вам вообще не нужен Spring TransactionManager. Поэтому я думаю, что JPATransactionManager игнорируется JMS , и ваши JMS-ресурсы должны быть транзакционными.

Теперь, когда ваш обработчик ошибок Camel «проглатывает» исключение с помощью handled(true), повторная доставка MQ не должна выполняться. Но MQ выполняет повторную доставку, когда исключение передается обратно брокеру.

Я ожидаю, что мой верблюжий маршрут будет выполняться в одной транзакции БД

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

...