我有一条骆驼路线,其中生产者是smb挂载,而消费者是ActiveMQ队列。
当SMB服务器无法从源SMB挂载删除文件时,我想回滚事务。但是,这是在事务的提交阶段发生的。
当使用 onCompletionExceptionHandler 时,我可以拦截该异常,但是捕获是在与文件连接的Exchange对象已经发送到目标ActiveMQ之后发生的。
是否有一种方法可以防止Camel首先提交事务或回滚事务,以使消息不发送到AMQ? Camel 2.17.2中存在此行为
答案 0 :(得分:0)
让我们研究不同的消息传递方式:
好,因此您基本上需要只一次语义。仅当在同一代理中的队列之间,数据库中的表之间或在本地磁盘上(或在同一“资源”内部)移动数据时,才能“实现”。
当您有多个协议/资源时,这几乎是不可能的,或者至少非常困难。有一些方法可以使用分布式事务处理协调器(例如Windows中的MSDTC或Java中的Atomikos)使用“两阶段提交”事务在某种程度上确保一次交付。这些将仅支持事务性资源,例如队列和数据库,而不支持文件系统,例如SMB。
另一种方法是使用sagas-pattern。但是,在这种情况下,这种模式可能有点过大。
那该怎么办?好吧-我可以想到至少一种方法:
Idempotent consumer pattern。这使Camel将每个消息的副本(或至少一个键,例如文件名)保存在内存中,以确保没有单个消息被发送一次以上。
// Something like this
from("smb://someplace?&idempotentKey=${file:name}&idempotent=true")
. // Whatnot
.to("activemq:queue:foobar");
请注意,如果需要更持久(但也更复杂)的东西,可以配置幂等存储库以将条目保留在数据库,磁盘或其他多个地方。