带有JMS事务和REST调用的骆驼

时间:2018-11-20 10:58:41

标签: java apache-camel

我需要从队列中读取消息,并调用REST服务进行发布。

然后,我正在研究与Camel进行的JMS事务,看来您可以设置maximumRedeliveries来再次处理队列消息,因此在失败的情况下回滚事务,我想知道它如何如果我们必须在同一条骆驼路线上调用一个REST服务来发布某些东西,那么该部分可以回滚吗?

maxDelivery conf:

errorHandler(new TransactionErrorHandlerBuilder()
        .loggingLevel(LoggingLevel.ERROR)
        .useOriginalMessage()
        .maximumRedeliveries(2)
        .logHandled(false)
        .logExhausted(true)
    );

该路线的伪代码:

//Reading message from the queue
from("activemq:AMQ.App.EMC2.In.PMQueue?jmsMessageType=Bytes").
    transacted().
    unmarshal(jaxbDataFormat).bean(pmMessageEnricher).
    to("direct:start-post");

//Then doing the post
from("direct:start-post").
    setHeader(Exchange.HTTP_METHOD, constant("POST")).
    setHeader(Exchange.CONTENT_TYPE, constant("application/json")).
    setBody(constant(pmMessageEnricher.toJson())).
    to("http://xxx").
    to("direct:start-somethingelse");

//Then doing something else
from("direct:start-somethingelse").
blabla...

假设start-somethingelse中发生异常,如何回滚REST调用?因为我们以无状态方式调用了外部服务。

1 个答案:

答案 0 :(得分:2)

您的疑问是正确的。如果发生JMS事务回滚,则POST请求无法回滚,因为服务提供者不属于JMS事务。交易仅在JMS经纪人和Camel JMS使用者之间进行(也请参见Camel transactional client)。

但是,如果发现处理错误,则可以应用所需的补偿逻辑。例如,使用另一个请求删除已发布的数据。

顺便说一句:不要混淆骆驼的重新交付和经纪人的重新交付!

骆驼的重新交付由Camel Errorhandler(而不是经纪人)完成。在您的示例中,它最多可以进行2次重新交付。但是请注意,骆驼重新交付不会重新处理整个路由,而只会重新处理失败的处理器

因此,如果to("http://xxx")失败并且Camel Errorhandler再次发送,则Camel仅重试to("http://xxx")

相反,如果您的JMS事务被回滚,则代理将消息重新发送给Camel,然后再次处理整个路由

请注意不要使用您的Camel错误处理程序“掩盖” JMS重新交付。