当前位置: 首页 > 知识库问答 >
问题:

如何在分布式事务期间锁定对象

葛驰
2023-03-14

我一直在看微服务和分布式事务。大多数文章都谈到了两阶段提交或Saga模式,但没有详细说明对象是如何被锁定的,这样当事务没有完成时,其他人就不能访问该数据

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

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

如果有一些代码样本的例子,这将是伟大的

共有2个答案

东门深
2023-03-14

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

客户服务将对事务中的客户记录执行操作,并向客户返回响应,例如订单 z 成功处理或订单 z 处理失败。

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

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

吴西岭
2023-03-14

大多数文章都讨论 2 阶段提交或 Saga 模式,但没有详细介绍对象是如何锁定的,因此当事务未完成时,其他人无法访问该数据。

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

然后2PC使用锁。它们需要作为协议的基本要素。事务管理器与参与者 - 资源进行通信。参与者是数据库。当 2PC 开始运行时,对 prepare 的调用意味着数据库对参与事务的所有行进行持久锁定。当事务管理器调用提交时,将释放此锁。请务必了解 2PC 之前的事务处于动态状态(而不是持久性)。它存储在内存中。调用 prepare 后,事务状态将永久存储,直到调用 commit 为止(此时协议可能会被不可用的事务管理器阻止 - 锁是持久的,系统等待事务管理器释放它)。

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

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

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

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

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

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

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

 类似资料:
  • 问题内容: 您将使用哪种分布式锁定服务? 要求是: 可以从不同的进程/机器看到的互斥(锁定) 锁定…释放语义 超时后自动释放锁-如果锁持有人死亡,它将在X秒后自动释放 Java实现 很高兴拥有:.Net实现 如果免费:死锁检测/缓解 易于部署,请参阅下面的注释。 我对诸如“可以通过数据库完成”或“可以通过JavaSpaces完成”之类的答案不感兴趣-我知道。我对现成的,现成的,经过验证的实现感兴趣

  • ShardingSphereTransactionManager SPI 名称 详细说明 ShardingSphereTransactionManager 分布式事务管理器 已知实现类 详细说明 XAShardingSphereTransactionManager 基于 XA 的分布式事务管理器 SeataATShardingSphereTransactionManager 基于 Seata 的分

  • ShardingSphere-Proxy 接入的分布式事务 API 同 ShardingSphere-JDBC 保持一致,支持 LOCAL,XA,BASE 类型的事务。 XA 事务 ShardingSphere-Proxy 原生支持 XA 事务,默认的事务管理器为 Atomikos。 可以通过在 ShardingSphere-Proxy 的 conf 目录中添加 jta.properties 来定

  • 通过 Apache ShardingSphere 使用分布式事务,与本地事务并无区别。 除了透明化分布式事务的使用之外,Apache ShardingSphere 还能够在每次数据库访问时切换分布式事务类型。 支持的事务类型包括 本地事务、XA事务 和 柔性事务。可在创建数据库连接之前设置,缺省为 Apache ShardingSphere 启动时的默认事务类型。

  • 背景 数据库事务需要满足 ACID(原子性、一致性、隔离性、持久性)四个特性。 原子性(Atomicity)指事务作为整体来执行,要么全部执行,要么全不执行。 一致性(Consistency)指事务应确保数据从一个一致的状态转变为另一个一致的状态。 隔离性(Isolation)指多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 持久性(Durability)指已提交的事务修改数据会被持久

  • 单文档原子性可满足大多数业务需求 在 MongoDB 中,对单个文档的操作是原子操作。 由于 MongoDB 文档数据模型,一个文档中通过嵌入式的文档和数组来表示传统关系数据库模型中的一对一、一对多关系,而不是通过文档之间的复杂关系来描述业务需求中的一对一、一对多关系。 所以单文档原子性可以满足实际生产中大多数关于事务的需求。 对于需要对多个文档(在单个或多个集合中)进行原子读写的情况,Mongo