【问题标题】:How to implement distributed end-to-end transactions with JMS如何使用 JMS 实现分布式端到端事务
【发布时间】:2015-07-28 22:21:47
【问题描述】:

我需要实现一个事务,该事务跨越在不同系统上运行并通过 JMS 进行通信的应用程序。实际上,我还不需要实现它,此时我只需要一个高层次的设计,并且对它可以实现它有一定的信心。

这是我需要做的。

假设我有两个应用程序(在不同的服务器上运行)维护一些必须保持一致的状态信息。为简单起见,假设它们都在跟踪单个变量 X 的值。

我需要发送应用程序执行以下操作:

  • 向对等方发送一条消息,请求将 X 设置为某个新值。
  • 如果对等方接受更改,则在本地进行更改。
  • 如果对等方拒绝更改,则保留 X 的值不变。
  • 如果发生通信错误或超时,则保持 X 不变。

接收者必须做类似的事情,整个事情必须是“事务性的”,因为我需要高度确信两个系统在某个固定的时间间隔内具有相同的 X 值,无论是否更改。我可以承受发生故障的罕见情况,只要至少一端的软件知道事情运行异常并且可以提醒操作员 X 的值可能不一致。

起初我认为使用 JMS 的功能会相对容易。但是在阅读了大量有关 JMS 的内容之后,现在我不这么认为了。有一些并发症,特别是:

  • 这是一个近乎实时的应用程序。如果无法在固定(短)时间内对双方进行更改,那么我需要中止更改。
  • 我在发送方和接收方之间没有单个 JMS 队列(或主题)。相反,我有其他进程(Oracle Service Bus 的东西)将消息从发送应用程序使用的 JMS 队列移动到接收应用程序读取的 JMS 队列。中间过程可能正在做诸如消息格式转换之类的事情,它也可能在不同的 JMS 实现之间进行调解(发送方使用一个供应商的 JMS,接收方使用另一个供应商的 JMS)。这意味着中间有可能出现问题——消息可能会延迟、丢失、无序传递等等。我不能依赖端到端的 JMS 交付保证。

我阅读了 JMS 确认的工作原理、不同的确认模式以及使用 JMS 事务。如果我错了,请告诉我,但我认为这些都不能解决我的问题。这些功能可以让我处理在将消息从我的应用程序传递到 JMS 代理时可能发生的任何错误,但是:

  • 不会给我端到端的任何东西
  • 不会对代理内部发生的问题采取任何措施(例如队列溢出、消息 TTL 过期等)

然后我开始阅读分布式事务处理和 XA。理论上,我认为这是我需要的。单个事务管理器和两阶段提交协议。但是,这不是我自己可以实现的,我需要使用现成的解决方案。所以我正在阅读 JTA,但我仍在努力理解这些概念。似乎 JTA 允许我从一个应用程序中拥有一个涉及一系列不同操作的事务,例如发送 JMS 消息,将数据写入数据库等......如果这些东西中的每一个都有一个符合 XA 的“资源管理器”,那么我可以将它们全部放在一个事务中(一切都会发生,或者一切都会发生)返回)来自我使用 JTA 的一个应用程序。

但我正在努力了解如何使用它。我没有一个应用程序,我有两个。而且我没有这些应用程序的 XA 兼容资源管理器。我必须写一个吗?以某种方式使用一个应用程序(例如数据库)?

有什么建议吗?

感谢和抱歉新手问题!

邓肯

【问题讨论】:

    标签: transactions jms distributed-transactions


    【解决方案1】:

    事务,甚至是分布式事务,通常只是确保某些消息被写入队列、从队列中读取或消息处理提交与某些数据库操作同时进行。除非您增加很多复杂性,否则它不会解决您的问题。

    您的问题看起来像是多个系统上的数据同步问题。我建议寻找其他方式来处理这种同步。

    一种常见的方法是将某个值(价格?)的最新更新连同一些时间戳(或如果此信息有效则需要考虑的其他信息)一起写入 JMS 主题。然后所有系统都可以跟上最新的信息(并安全地拒绝带有“过时”信息的出版物)。类似的事情可以解决您的问题吗?

    如果你的不同系统有不同的底层数据库,你当然可以使用 XA 事务(周围有open source XA transaction managers)并将新值 X 提交到两个数据库。这将是“安全的”,但另一方面,它会使您的系统保持紧密耦合,这通常不是一个好主意。

    【讨论】:

    • 是的,“多个系统上的数据同步问题”正是我面临的问题。
    • 但如果系统以不一致的数据视图结束,则会产生安全隐患。这就是为什么我不想自己设计这个,我想把它建立在一个经过验证的解决方案上,这就是我选择 XA 的原因。但是我不知道如何使用它,除非我有一个应用程序写入两个数据库,并且我不想通过网络进行远程数据库更新。需要通过 JMS 发送数据。有什么办法可以在这里使用 XA 吗?
    • 好吧,我想不出一个。 JMS 并不是真正用来自动决定新的分布式应用程序状态(这是您正在尝试的)。查找分布式时钟或其他东西来弄清楚这个问题到底有多复杂。这就是为什么您通常通过使一个系统成为“主”系统来避免这种情况,并且来自它的任何数据都应该被视为“真正的 X”。也许等着看另一个答案是否不同。
    • 没有其他回应 :-( Petter,我认为你是 100% 正确的 - 但不幸的是,这不是我希望的答案。我有很多限制 - 这不是一个新系统。例如,我不能简单地让一个系统成为“主控”——不同的系统在不同的时间处于控制之中,我无法改变这一点。引入了基于 IP 的 JMS 以取代专用的自定义消息接口电路。看起来解决方案必须在应用层保留遗留的消息处理语义。
    • 也许是这样,有时没有灵丹妙药。故障安全数据同步的一般问题确实非常困难。使用标准技术将其解耦更加困难。
    猜你喜欢
    • 2012-08-31
    • 2013-03-16
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多