跨多个微服务的 2PC 分布式事务?
2PC distributed transactions across many microservices?
我阅读了一些有关 2 阶段提交/XA 分布式事务 以及 JTA 如何支持它的信息。似乎有许多资源管理器 - RM(例如 RDBMS 或 JMS),以及一个 TransactionManager (TM) 实例来管理跨多个 RM 的全局事务。
我知道用Saga模式更好,但想想还是很有意思:
- 2PC/XA 分布式事务是否可以仅从一个应用程序和一个 TM 与多个 RM 进行事务?
- 如果没有 - 如何在许多微服务之间使用 2PC/XA 分布式事务 以提供使用 2PC 的能力,如果 每个微服务只能访问自己的数据库?我很乐意看到一个例子
- 我们是否需要使用 TransactionManager 服务作为一个单独的微服务来提供许多微服务之间的 2PC?
更新: 在 JTA 世界中 TransactionManager
不提供 REST API 用于跨微服务管理事务。 LIXA 提供了这种能力。 Article with examples 除了答案:)
跨微服务,事务需要通过公开准备和提交 API 来完成。还需要一个事务管理器来协调事务。
例如,假设有 2 家不同的银行,银行 1 Account_A 的 100 美元必须转账到银行 2 的 Account_B。进一步假设中央银行当局负责完成交易
2PC 的工作方式如下:
中央银行当局(交易管理器)将收到从银行 1 的 Account_A 向银行 2 的 Account_B 转账 100 美元的请求。
a. https://CentralBank/Transaction?from=Bank1-Account_A&to=Bank2-Account_B&amount=100
中央银行将使用一些交易 ID = 123 将其保存到其交易数据库中。它还将调用 return 交易 ID,以便稍后可以调用以获取状态交易量。
a. add transaction 123 in database with status open
准备阶段事务管理器将发出以下 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
COMMIT PHASE 一旦在 Prepare 阶段的两个调用都获得成功响应,它就会进入 Commit 阶段,在该阶段发出以下命令:
a. move transaction 123 to committed state
b. https://Bank1/Commit?transactionid=123
c. https://Bank2/Commit?transactionid=123
一旦在提交阶段的两个调用都获得成功响应,中央银行就可以将交易转移到完成状态(可选)
如果 PREPARE 或 COMMIT 阶段的任何步骤失败,则事务协调器通过发出以下命令中止事务:
a. move transaction 123 to Failed state
b. https://Bank1/Rollback?transactionid=123
c. https://Bank2/Rollback?transactionid=123
上面的问题是分布式原子提交的形式,而2PC是一种实现方式。另请注意,2PC 有很多缺点,例如在 PREPARE 阶段中央银行崩溃后会怎样。此外,如果 4.c 步骤失败但 4.b 成功,等等。讨论这些本身就是一项非常广泛的研究,但仍然需要注意。尽管 2PC 有很多缺点,但由于其简单性而被广泛使用。
Do we need to use TransactionManager service as a separate microservice to provide 2PC between many microservices?
理论上没有。如果你仔细观察任何一家银行(Bank1 或 Bank2)也可以充当交易管理器(它只需要一个单独的数据库 table 交易),但实际上很多时候它是作为单独的微服务保留。
我阅读了一些有关 2 阶段提交/XA 分布式事务 以及 JTA 如何支持它的信息。似乎有许多资源管理器 - RM(例如 RDBMS 或 JMS),以及一个 TransactionManager (TM) 实例来管理跨多个 RM 的全局事务。
我知道用Saga模式更好,但想想还是很有意思:
- 2PC/XA 分布式事务是否可以仅从一个应用程序和一个 TM 与多个 RM 进行事务?
- 如果没有 - 如何在许多微服务之间使用 2PC/XA 分布式事务 以提供使用 2PC 的能力,如果 每个微服务只能访问自己的数据库?我很乐意看到一个例子
- 我们是否需要使用 TransactionManager 服务作为一个单独的微服务来提供许多微服务之间的 2PC?
更新: 在 JTA 世界中 TransactionManager
不提供 REST API 用于跨微服务管理事务。 LIXA 提供了这种能力。 Article with examples 除了答案:)
跨微服务,事务需要通过公开准备和提交 API 来完成。还需要一个事务管理器来协调事务。
例如,假设有 2 家不同的银行,银行 1 Account_A 的 100 美元必须转账到银行 2 的 Account_B。进一步假设中央银行当局负责完成交易 2PC 的工作方式如下:
中央银行当局(交易管理器)将收到从银行 1 的 Account_A 向银行 2 的 Account_B 转账 100 美元的请求。
a. https://CentralBank/Transaction?from=Bank1-Account_A&to=Bank2-Account_B&amount=100
中央银行将使用一些交易 ID = 123 将其保存到其交易数据库中。它还将调用 return 交易 ID,以便稍后可以调用以获取状态交易量。
a. add transaction 123 in database with status open
准备阶段事务管理器将发出以下 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
COMMIT PHASE 一旦在 Prepare 阶段的两个调用都获得成功响应,它就会进入 Commit 阶段,在该阶段发出以下命令:
a. move transaction 123 to committed state b. https://Bank1/Commit?transactionid=123 c. https://Bank2/Commit?transactionid=123
一旦在提交阶段的两个调用都获得成功响应,中央银行就可以将交易转移到完成状态(可选)
如果 PREPARE 或 COMMIT 阶段的任何步骤失败,则事务协调器通过发出以下命令中止事务:
a. move transaction 123 to Failed state b. https://Bank1/Rollback?transactionid=123 c. https://Bank2/Rollback?transactionid=123
上面的问题是分布式原子提交的形式,而2PC是一种实现方式。另请注意,2PC 有很多缺点,例如在 PREPARE 阶段中央银行崩溃后会怎样。此外,如果 4.c 步骤失败但 4.b 成功,等等。讨论这些本身就是一项非常广泛的研究,但仍然需要注意。尽管 2PC 有很多缺点,但由于其简单性而被广泛使用。
Do we need to use TransactionManager service as a separate microservice to provide 2PC between many microservices?
理论上没有。如果你仔细观察任何一家银行(Bank1 或 Bank2)也可以充当交易管理器(它只需要一个单独的数据库 table 交易),但实际上很多时候它是作为单独的微服务保留。