【问题标题】:How to lock an object during a distributed transaction如何在分布式事务期间锁定对象
【发布时间】:2020-04-23 10:06:38
【问题描述】:

我一直在阅读有关微服务和分布式事务的信息。大多数文章都在讨论 2 阶段提交或 Saga 模式,但没有详细说明对象是如何锁定的,这样其他人就无法在事务未完成时访问该数据。

如果我有客户服务和订单服务,并且我发起了锁定客户资金的请求,直到订单处理完毕。在分布式系统中,这是如何实现的。

在数据库中是否可以显式锁定一行,然后另一个请求去解锁该行,或者这是使用客户表上的锁定字段实现的,第一个事务将其设置为锁定,一旦订单完成,它返回并将其设置为解锁或清空该行?

如果有一些带有代码示例的示例会很棒

【问题讨论】:

标签: microservices distributed-transactions


【解决方案1】:

在微服务世界中,事务边界位于服务内。服务依赖于最终的一致性。因此,在您的示例中,订单服务将发送一个请求(同步或异步,具体取决于应用程序语义和规模要求),例如 从客户 y 中为订单 z 扣除 x 金额

客户服务将对交易中的客户记录执行操作,并向客户返回响应,例如 Order z 已成功处理Order z 处理失败

然后,订单服务可以根据收到的响应触发订单的确认/失败过程。

应用程序通常在可用性和 ACID 强一致性之间进行选择。大多数基于微服务的场景需要可用性和高可扩展性,而不是强一致性,这意味着服务之间的通信是异步的,最终会达到一致的状态。

【讨论】:

    【解决方案2】:

    大多数文章都讨论 2 Phase commit 或 Saga 模式,但没有 详细说明一个对象是如何被锁定的,这样其他人就无法访问 交易未完成时的数据。

    2PC 被定义为阻塞。这意味着,如果管理 2PC 事务的事务管理器出现故障,则 2PC 将无法解决。事务管理器是单点故障。 如果确保重新启动失败的事务管理器,那么即使 2PC 协议被认为是阻塞的,您也可以确保事务管理器可用并且解决方案不会被阻塞。

    然后 2PC 使用锁。它们是协议的基本元素。事务管理器与参与者 - 资源进行通信。参与者是数据库。当 2PC 开始运行时,调用 prepare 意味着数据库对参与事务的所有行进行持久锁定。这个锁在事务管理器调用提交时被释放。 重要的是要了解 2PC 之前的事务是在进行中(不是持久的)。它存储在内存中。在调用准备之后,事务状态被持久存储,直到调用提交(那时协议可能被不可用的事务管理器阻塞 - 锁是持久的,系统等待事务管理器释放它)。

    从 2PC 的角度来看,这是关于锁定的。但是从数据库的角度来看,有事务锁。 当您更新数据库中的一行时,事务就在进行中(存储在内存中)。那时数据库需要确保并发更新不会破坏您的数据。一种方法是锁定行并且不允许并发更新。 但是,大多数数据库不会锁定行 - 默认情况下,取决于隔离级别 - 在这些情况下,因为它们使用快照隔离(MVCC,https://en.wikipedia.org/wiki/Snapshot_isolation)。这尤其意味着该行被乐观锁定,并且数据库允许其他事务更新该行。

    但是! 2PC prepare 不能乐观处理。当数据库回复“OK”以准备来自事务管理器的请求时,该行就被锁定了。

    另外,您无法手动管理此锁定。如果你试图这样做,你会破坏 2PC 的一致性保证。

    在您的示例中,有客户服务和订单服务。当 2PC 事务跨越这两个服务时。然后客户更新数据库,订单服务也更新数据库。数据库中仍在运行中的事务。然后请求完成并且事务管理器命令进行中的事务提交。它运行2PC。它在客户服务数据库事务上调用准备,然后在订单服务事务上调用提交。

    如果您使用 saga 模式,那么 saga 会跨越这两个服务。从事务的角度来看,客户服务会创建一个数据库中的事务并立即提交它。然后呼叫转到订单服务,同样的事情也会发生。当请求完成时,saga 会检查一切是否正常。当发生故障时,将调用补偿回调。

    从易用性的角度来看,故障是“麻烦”。对于 saga,您需要在回调方法中自行维护故障解决方案。对于 2PC,故障解决由回滚调用自动处理。

    注:我试图在这里总结2PC:https://developer.jboss.org/wiki/TwoPhaseCommit2PC 我不确定解释是否足够理解,但您可以尝试检查。你可以让我知道那里的错误解释。谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多