6

我阅读了一些关于2 Phase Commit/XA 分布式事务以及 JTA 如何支持它的信息。似乎有许多资源管理器 - RM(例如 RDBMS 或 JMS),以及一个跨多个 RM 管理全局事务的TransactionManager (TM)实例。 TM <-> RM 通信

我知道最好使用Saga 模式,但想想还是很有趣:

  1. 2PC/XA 分布式事务是否可以仅通过一个应用程序和一个 TM 与多个 RM 进行事务
  2. 如果没有 -如果每个微服务只能访问自己的数据库,如何在许多微服务之间使用 2PC/XA 分布式事务来提供使用 2PC 的能力?我很高兴看到一个例子
  3. 我们是否需要将TransactionManager服务作为一个单独的微服务来提供多个微服务之间的 2PC?

UPD: 在 JTA 世界 TransactionManager 中,不提供 REST API来管理跨微服务的事务。LIXA 提供了这种能力。除了答案之外还有示例的文章:)

4

1 回答 1

6

在微服务中,事务需要通过公开 Prepare & Commit API 来完成。还需要有一个事务管理器来协调事务。

例如,假设有 2 个不同的银行,并且必须将来自 Bank1 的 Account_A 的 100 美元转移到 Bank2 的 Account_B。此外,假设中央银行机构负责交易以完成 2PC 的工作方式,如下所示:

  1. 中央银行机构(交易经理)将收到将 100 美元从 Bank1 的 Account_A 转移到 Bank2 的 Account_B 的请求。

    a. https://CentralBank/Transaction?from=Bank1-Account_A&to=Bank2-Account_B&amount=100
    
  2. 中央银行会将其保存到其交易数据库中,其中一些交易 ID = 123。它还将返回交易 ID 以供调用,以便稍后它可以调用以获取交易状态。

    a. add transaction 123 in database with status open
    
  3. PREPARE PHASE事务管理器将发出以下 RPC 命令:

    a. https://Bank1/Prepare?Account=Account_A&money=100&action=subtract&transactionid=123
    b. https://Bank2/Prepare?Account=Account_B&money=100&action=add&transactionid=123
    
  4. 提交阶段一旦它在准备阶段的两个调用都获得成功响应,然后它会移动到提交阶段,它会发出以下命令:

    a. move transaction 123 to committed state
    b. https://Bank1/Commit?transactionid=123
    c. https://Bank2/Commit?transactionid=123
    
  5. 一旦在提交阶段的两个调用都获得成功响应,中央银行可以将交易转移到已完成状态(可选)

  6. 如果 PREPARE 或 COMMIT 阶段的任何步骤失败,则事务协调器通过发出以下命令中止事务:

    a. move transaction 123 to Failed state
    b. https://Bank1/Rollback?transactionid=123
    c. https://Bank2/Rollback?transactionid=123
    

上面的问题是分布式原子提交的形式,而 2PC 是一种方法。另请注意,2PC 有很多缺点,例如在准备阶段中央银行崩溃之后会怎样。此外,如果 4.c 步骤失败但 4.b 成功等等怎么办。讨论这些本身就是非常广泛的研究,但仍然需要注意。尽管 2PC 有很多缺点,但由于其简单性而被广泛使用。


我们是否需要将 TransactionManager 服务作为一个单独的微服务来提供多个微服务之间的 2PC?

理论上不会。如果您仔细观察任何银行(Bank1 或 Bank2)也可以充当事务管理器(它只需要一个单独的数据库表 Transaction),但实际上很多时候它被保存为单独的微服务。

于 2020-12-23T22:47:49.027 回答