【问题标题】:File rollback when unable to delete file from smb无法从 smb 删除文件时文件回滚
【发布时间】:2019-04-18 14:26:26
【问题描述】:

我有一个骆驼路线,其中生产者是 smb 挂载,消费者是 ActiveMQ 队列。

当 SMB 服务器无法从源 SMB 挂载中删除文件时,我想回滚事务。然而,这发生在事务的提交阶段。

我可以在使用onCompletionExceptionHandler时拦截异常,但是在与文件连接的Exchange对象已经发送到目标ActiveMQ之后才发生捕获。

有没有办法阻止 Camel 首先提交事务或回滚事务以使消息不发送到 AMQ? Camel 2.17.2 中存在此行为

【问题讨论】:

    标签: apache-camel activemq


    【解决方案1】:

    让我们看看不同的消息传递模式:

    • 至少一次 - 消息在传递到目标后从源中删除。同一条消息可以多次发送。
      • 这就是你现在得到的。
    • 最多一次 - 消息在传递到目标之前从源中删除。数据可能会丢失。
      • 可能不是您想要的。
    • 恰好一次 - 消息将在发送到目标的同时从源中删除。
      • 圣杯。很难实现。

    好的,所以你本质上想要一个 Exactly once 语义。这可以“仅”在同一代理中的队列之间、数据库中的表之间或通过在本地磁盘(或在同一“资源”内部)移动文件时实现。

    当您有多个协议/资源时,这几乎是不可能的,或者至少非常困难。有一些方法可以使用分布式事务协调器(例如 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");
    

    请注意,如果您想要更持久(但也更复杂)的东西,您可以配置一个幂等存储库以将条目保存在数据库、磁盘或多个其他地方。

    【讨论】:

    • 嗨,Petter,我需要使用 reactPWALink-state apollo 配置项目可以请您指导吗到一些教程,这样我就可以在最好的水平上配置它。
    • @Profer 我想这最好作为另一个带有相关标签的问题来完成
    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 2017-02-22
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多