我正在使用命令事件驱动的系统,使用JMS和Apache Camel进行路由。在以下情况中:
我向系统发送请求 - 回复命令“X”。
系统通过交易的驼峰路线接收“X”。
在处理“X”时,系统会发出几个事件,“Y”和& “Z”, 但作为交易路线的一部分,这些不应该被刷新 直到交易完成。
发生运行时异常 - 应该导致事务发生 回滚。
我希望能够拦截异常并使用真实的消息(而不是异常)回复客户端。因此我开始实现错误处理程序:
onException(RuntimeException.class)
.handled(true)
.markRollbackOnly()
.filter(header(Header.REPLY_TO.getName()).isNotNull())
.to(DESTINATION_FOR_EXCEPTION_HANDLING)
.to(DESTINATION_FOR_REPLIES);
其中:
我遇到的问题是如果我包含“markRollbackOnly()”它:
如果我不包含它,那么:
如何配置camel以防止在事务中刷新消息,并且能够将异常转换为处理过的错误消息?
答案 0 :(得分:0)
如果发送到这两个目标的onException使用的是与from相同的Camel组件,那么您需要使用单独的组件,因此它们是独立的。因为回滚会导致它们全部回滚。
假设您使用ActiveMQ,您只需声明两个组件
<bean id="activemq" ...>
<bean id="activemq2" ...>
然后在onException中使用activemq2。然后可以配置为使用相同的brokerUrl和所有这些。对于第二个,您可能需要将其设置为transacted = false。
答案 1 :(得分:0)
我尝试过Claus方法,但由于某种原因无法使其工作,我必须误解或设置错误。
最终我通过在内部传播第二个事务来解决这个问题,一个错误处理程序,然后我可以“markRollbackOnlyLast”第二个事务,但在主事务上回复“好”消息:
TransactionTemplate newTransactionTemplate = new TransactionTemplate(platformTransactionManager);
newTransactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
Policy requireNewTransaction = new SpringTransactionPolicy(newTransactionTemplate);
onException(RuntimeException.class)
.onWhen(header(Header.REPLY_TO.getName()).isNotNull())
.log(LoggingLevel.ERROR, EXCEPTION_STACKTRACE)
.to(PROCESSOR_FOR_EXCEPTION_HANDLING)
.to(PROCESSOR_FOR_REPLY)
.handled(true)
.markRollbackOnlyLast();
from(FROM)
.policy(requireNewTransaction)...