跨服务交易或原子性

时间:2019-03-14 16:07:16

标签: transactions atomic distributed-computing soa distributed

我有一个实时程序,该程序对服务A进行网络调用以执行有状态操作,而对服务B进行网络调用以记录该操作的历史记录。唯一的问题是:

  1. 如果B失败,我们必须还原操作A(出于“原因”,我们需要完整的历史记录,否则该操作根本不会发生)。换句话说,除非我们明确且成功地调用了服务以采取措施,否则我们将无法编写审核跟踪(即,我们无法更改先调用审核跟踪再调用服务的顺序)。
  2. 我们无法拥有B中历史记录的无效顺序(这是A的有状态方面)

我有一些想法,没有一个是理想的:

  • 在执行操作之前获取A的状态(这是一种可用方法),如果对B的调用失败,我们可以以原始状态再次调用第一个服务。方法的问题是,对A的“还原”调用也可能会失败。
  • 在较高级别上,这似乎可以通过服务级别的“事务”解决(两个服务调用都成功或都失败)。主要算法似乎是2-phase commit,但似乎没有什么可以使用的,因为我们不拥有要调用的服务,因此不能保证稳定的存储,也不能为以下功能添加功能表示同意“交易协调员”
  • 在我们这边尽最大努力模仿交易。在我看来,这是一种相当复杂的方法,很难或不可能做到正确
  • 具有进入“最终一致状态”的能力。但是,从2开始,某些排序是不可能的,因此我们必须等待所有排队的操作完成后才能继续。这将使我们的服务可能无法实时运行。

有什么解决方案可以使日志的完整镜像满足100%正确性的要求?

1 个答案:

答案 0 :(得分:1)

您没有提到所有服务都在通信的协议,因此,我假设使用HTTP。

就像您说的那样,所有可能的解决方案似乎都不适合您。

  1. 对于服务而言,在状态检查之前或之后更改状态太容易了,就像您说的那样,此后的任何补救措施也很容易失败。

  2. 我认为在您概述了两阶段提交的情况下,这是不可能的。即使您确实拥有所有服务,也很难仅使用HTTP来实现此目的。

  3. 我同意

  4. 在所有选项中,此选项都有其分支。这完全取决于您对“实时”的要求。每当有人这样说时,我会问“你是什么意思?”没有什么是“实时”的,一切都需要一些时间来处理。总是有一段时间,某人或某事要求完成某件事才真正完成!毫秒秒和分钟之间的差异只是一个问题或要求,您还需要投入多少钱。

因此,您说通过HTTP调用您的服务(简称为X)再次通过HTTP分别成功调用了两个服务A和B。如果您同时有多个对X的调用,则无法(或至少很难做到)确保对A的调用顺序与对B的调用顺序相同。但这又取决于您的要求和要求系统正在运行以及如何运行,也许每天只有一个电话打给您的系统?

我个人建议使用队列,并转向事件驱动的体系结构。即使使用了最终一致的系统,您也可以使其运行在热状态并获得所需的“实时”,这只会使您付出更多!

我希望这对您有用。听到您对我的建议的想法,我非常感兴趣。