Apache camel 如果任何子消息失败,如何回滚拆分器的整个事务

Apache camel 如果任何子消息失败,如何回滚拆分器的整个事务,apache-camel,rollback,Apache Camel,Rollback,当前用例: 在下面的配置中,我们尝试使用自定义迭代器处理器拆分父消息,并根据其内容将不同的端点分配给测试处理器内的不同子消息 from("endpoint") .split().method(iteratorProcessor, "execute") .shareUnitOfWork() .stopOnException() .bean(testProcessor, "process") .receipientList(header("desti

当前用例: 在下面的配置中,我们尝试使用自定义迭代器处理器拆分父消息,并根据其内容将不同的端点分配给测试处理器内的不同子消息

from("endpoint")    
    .split().method(iteratorProcessor, "execute")
    .shareUnitOfWork()
    .stopOnException()
    .bean(testProcessor, "process") 
    .receipientList(header("destination"));
有了以上内容,成功案例就如预期的那样发挥作用

问题: 在拆分之后,第一条消息发布成功,第二条消息发布失败,我们观察到第二条子消息单独被定向到错误处理程序

要求
如果整个过程中出现任何故障,我们希望将in消息重定向到错误处理程序(完成回滚),并且不发布任何其他子消息。

OneException子句提供了使用原始消息的选项

从Camel文档:

onException(MyOrderException.class)
.useOriginalMessage()
.handled(true)
.to("jms:queue:order:failed");

OneException子句提供了使用原始消息的选项

从Camel文档:

onException(MyOrderException.class)
.useOriginalMessage()
.handled(true)
.to("jms:queue:order:failed");

欢迎来到堆栈溢出

如果出现错误,由于语句
stopOnException()
,将中止处理

这意味着您的目标要进行一次完整的回滚

  • 您可以处理所有尚未处理的记录
  • 您的问题是已成功处理的记录
对于这些,作为回滚的一部分,您必须运行补偿逻辑。例如,如果已处理的记录写入数据库,则可以在拆分器发生故障时删除这些记录

由于评论而添加

根据,由于您使用了
shareUnitOfWork()
,在拆分器完成时,您应该只收到一条错误消息,并且至少发生了一条错误(而不是每个失败的子消息都有一条错误消息)。因此,如果在错误处理程序中也使用了
useOriginalMessage()
,则应该会收到原始in消息

如果这不起作用,它可能会与
stopOnException()
发生冲突(从未尝试过)。尝试删除
stopOnException()
并检查它是否可以这样工作


您不能直接
补偿已传递的JMS消息,但可以构建一个可在事后触发的
补偿。例如,将失败的消息从错误处理程序发送到另一个队列,其使用者回滚第一条消息所做的任何操作。

欢迎使用堆栈溢出

如果出现错误,由于语句
stopOnException()
,将中止处理

这意味着您的目标要进行一次完整的回滚

  • 您可以处理所有尚未处理的记录
  • 您的问题是已成功处理的记录
对于这些,作为回滚的一部分,您必须运行补偿逻辑。例如,如果已处理的记录写入数据库,则可以在拆分器发生故障时删除这些记录

由于评论而添加

根据,由于您使用了
shareUnitOfWork()
,在拆分器完成时,您应该只收到一条错误消息,并且至少发生了一条错误(而不是每个失败的子消息都有一条错误消息)。因此,如果在错误处理程序中也使用了
useOriginalMessage()
,则应该会收到原始in消息

如果这不起作用,它可能会与
stopOnException()
发生冲突(从未尝试过)。尝试删除
stopOnException()
并检查它是否可以这样工作


您不能直接
补偿已传递的JMS消息,但可以构建一个可在事后触发的
补偿。例如,将失败的消息从错误处理程序发送到另一个队列,该队列的使用者将回滚第一条消息所做的任何操作。

对,如果由于使用StopOneException而出现任何失败,则会进行拆分,这样可以正常工作。在这里,我们的目的地是一个队列,所以如果bean中出现任何故障,或者在处理某些消息后向队列发送消息时出现任何故障。我们无法回滚,因为上一次已提交。所以,我想检查一下骆驼是否有任何东西可以实现这一点。此外,错误处理程序正在接收被拆分但在消息中不是实际的子消息。由于您的评论,我扩展了我的答案,而拆分时,如果由于我们使用StopOneException而出现任何失败,它工作正常。在这里,我们的目的地是一个队列,所以如果bean中出现任何故障,或者在处理某些消息后向队列发送消息时出现任何故障。我们无法回滚,因为上一次已提交。所以,我想检查一下骆驼是否有任何东西可以实现这一点。此外,错误处理程序正在接收子消息,该子消息被拆分,但在消息中不是实际的。由于您的评论,我扩展了我的答案