java - 带有 JMS 事务和 REST 后调用的骆驼
问题描述
我需要从队列中读取消息并调用 REST 服务进行发布。
然后,我正在查看与 Camel 的 JMS 事务,看起来你可以设置一个maximumRedeliveries
来再次处理队列消息,所以在失败的情况下回滚事务,我想知道如果在同一个骆驼路线中它如何工作我们必须调用 REST 服务来发布某些内容,该部分如何回滚?
最大交付配置:
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 post 调用?因为我们以无状态的方式调用外部服务。
解决方案
你的怀疑是正确的。在 JMS 事务回滚的情况下,不能回滚 POST 请求,因为服务提供者不是 JMS 事务的一部分。该事务只是在 JMS 代理和 Camel JMS 使用者之间(另请参见Camel 事务客户端)。
但是,如果您发现处理错误,您可以应用所需的补偿逻辑。例如,使用另一个请求删除已发布的数据。
顺便说一句:不要混淆骆驼重新交付和经纪人重新交付!
骆驼重新交付由骆驼错误处理程序(而不是代理)完成。在您的示例中,它最多执行 2 次重新交付。但请注意,Camel 重新交付并不会重新处理整个路线,而只是重新处理发生故障的处理器。
因此,如果to("http://xxx")
失败并且 Camel Errorhandler 重新交付,Camel 仅重试to("http://xxx")
.
相反,如果您的 JMS 事务被回滚,代理将消息重新传递给 Camel,并且整个路由会再次被处理。
注意不要用 Camel 错误处理程序“掩盖”JMS 重新传递。