当前位置: 首页 > news >正文

数据一致性问题剖析与实践(三)——分布式事务的一致性问题

一、前言

之前我们讨论了几种场景的一致性问题

  • 冗余数据存储中的一致性问题
  • 分布式共识中的一致性问题
  • 单机事务中的一致性问题

本文将围绕分布式事务中的一致性问题展开讨论。

二、分布式环境的最大难题

相对于单机环境,分布式环境中,一致性问题最大的挑战,就是不可靠的网络和时钟。

2.1 不可靠的网络

互联网及多数数据中心内部网络为异步网络 。在此网络中,节点间数据包传输存在诸多不确定性。消息发送后等待响应期间,状况百出:

发送节点 不可靠的网络 远程接收节点 发送请求 可能滞留 传递请求 alt [请求滞留] [请求正常传输] 可能崩溃或暂时无响应 正确处理请求,回复消息 回复消息可能丢失 送达回复消息 alt [消息丢失] [消息送达] alt [节点异常] [正常处理] 重发请求 传递重发请求 loop [重发消息] alt [未收到响应] 发送节点 不可靠的网络 远程接收节点
  • 请求可能滞留于消息队列或因网络分区无法及时抵达远程接收节点;
  • 远程接收节点可能崩溃、暂时无法响应(如执行长时间垃圾回收);
  • 即便远程节点正确处理请求,回复消息也可能在网络中丢失。

由于网络延迟不确定,数据包及回复消息皆可能丢失或延迟,发送者仅知未收到响应,却难判原因,常只能不断重发消息 。

2.2 不可靠的时钟

现代计算机内部至少有两种不同的时钟,墙上时钟返回的是自 1970 年 1 月 1 日以来的秒数或毫秒数,即 UNIX 时间戳;单调时钟是一个单调自增的时间计数器,常用于测量持续的时间间隔。

每一台计算机都拥有自己的石英时钟设备,也就是说每台机器都维护了自己本地的时间版本。但是这些石英钟设备并非绝对准确,可能存在时钟漂移现象(运行速度加快或减慢),一个节点上的时间可能与另一个节点上的时间完全不同。例如谷歌假设其服务器的时钟偏移为 200ppm(百万分之一),相当于如果每 30 秒与 NTP 服务器重新同步一次,则可能出现的最大偏差为 6ms,如果每天同步一次,则最大偏差为 17s。

由于最后写入的消息是由一个节点上的时钟来决定的,这就避免不了一个事实:这个时钟可能是错误的。所以通过时间戳来进行跨节点的事件排序依然无法解决下面这几类问题:

  • 后续发生的写操作可能无法覆盖较早版本的值,原因是后者节点的时钟太快了,导致一些数据被偷偷地丢弃;
  • 由于时钟精度的限制,两个节点可能产生了完全相同的时间戳;
  • 闰秒会产生一分钟为 59 秒或 61 秒的调整,这可能会使系统出现混乱。

虽然墙上时钟可以与 NTP(Network Time Protocol)服务器、GPS 或数据中心内部设立的原子钟等更加精确的时钟同步,纠正自己的时间,但如果两者的时钟差距很大,在时间重置后应用程序可能会看到时间突然倒退或向前跳跃现象,这会引发新的时钟问题:NTP 同步可能会产生时钟回拨,使得后写入的数据拥有较旧=早的时间戳,导致该写入被抛弃。

因此节点的时钟可能与其它节点存在明显的不同步,尽管可以设置 NTP 服务器进行纠正,但是依靠时钟进行事件排序仍然存在一定的风险,所以基于递增计数器的逻辑时钟或全局时钟是比物理时钟更可靠的方式。逻辑时钟依据事件的相对前后关系为其分配唯一 ID,并按照 ID 大小判断消息的新旧,这就避免了时间排序潜在的冲突。

三、理论基础

3.1 事务特性 ——ACID

单机事务的 ACID 特性,是保障数据正确性与一致性的基础准则

  • 原子性(Atomicity):事务被视为一个不可分割的整体,所有操作要么全部成功提交,要么全部失败回滚。例如在银行转账中,从账户 A 扣款与向账户 B 入账必须同时完成,若扣款成功但入账失败,整个事务需回滚,确保资金不会凭空消失或增加 。

  • 隔离性(Isolation):多个并发事务之间相互隔离,互不干扰。不同隔离级别(读未提交、读已提交、可重复读、串行化)定义了事务间对数据访问的可见范围,避免脏读、不可重复读和幻读等问题 。

    其本质是控制数据的访问范围,在并发场景下,实现不同隔离级别下的“对外一致性”

  • 持久性(Durability):一旦事务提交成功,其对数据的修改将永久保存,即使系统出现故障(如断电、宕机)也不会丢失。银行交易完成后,账户余额的变更会持久化存储,确保数据的可靠性 。

  • 一致性(Consistency):事务执行前后,数据需从一个合法状态转换到另一个合法状态。如电商下单时,库存数量必须与订单数量保持逻辑一致,不能出现超卖现象,以维持业务规则的正确性 。

只有保证了原子性、隔离性、持久性的前提下,才能实现一致性,一致性是事务的目的。

3.2 BASE理论

BASE 理论是 eBay 架构师对大规模互联网分布式系统实践的总结,并在 ACM 上发表了[3] Base: An Acid Alternative一文,其核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

BASE 是对 CAP 中一致性和可用性权衡的结果,对分布式系统提出了三个概念:

  • 基本可用(Basically Available)
  • 软(弱)状态(Soft State)
  • 最终一致性(Eventually Consistent)

BASE 理论表明要实现系统的横向扩展,就要对业务进行功能分区,将数据的不同功能组迁移到相互独立的数据库服务器上。由于降低了事务的耦合度,就不能单纯依赖数据库的约束来保证功能组之间的一致性,BASE 提出使用消息队列来异步执行解耦后的命令。

BASE 理论强调的最终一致性允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许多个节点的数据副本存在数据延时。但是在一定的期限内,应当保证所有副本数据一致,达到数据的最终一致。

3.3 一致性分类

因为一致性的实现有相当大的代价,但是在实际项目需求中,我们针对一致性的诉求是不同的,所以我们可以根据自己的应用场景去实现自己的一致性。

常见一致性分类如下:

  • 强一致性:任何时刻,所有节点对同一份数据的读取结果完全相同。以金融交易系统为例,用户转账后,无论从哪个节点查询余额,都应立即显示更新后的数值。这种一致性等级能最大程度保证数据准确性,但实现难度高,通常需通过严格的锁机制、同步协议(如两阶段提交)来确保所有节点数据实时同步,这会显著降低系统并发性能。
  • 最终一致性:允许系统在一段时间内存在数据不一致,但经过一段时间后,所有节点数据将达成一致。例如,社交平台的点赞数更新,用户点赞后,部分节点可能稍晚才显示点赞数量变化。这种模型适用于对实时性要求不高的场景,通过异步复制、消息队列等技术实现,在保障数据一致性的同时,提升了系统吞吐量和可用性。
  • 顺序一致性:所有节点看到的操作顺序相同,不要求操作立即同步到所有节点,但需保证操作执行顺序一致。在分布式日志系统中,各节点记录的操作顺序必须相同,以便后续分析和恢复。它在一致性和性能之间取得平衡,相比强一致性,对系统性能影响较小,但仍需协调各节点操作顺序。
  • 弱一致性:对数据一致性要求最低,仅保证部分数据在特定条件下的一致性。在某些实时性要求极低的缓存场景中,允许数据存在较大延迟和不一致。虽然牺牲了一致性,但能大幅提升系统性能和响应速度,适用于对数据一致性敏感度低的业务。

四、原子性

很多时候我们讲的分布式事务解决方案,都是围绕事务的原子性来展开的。

4.1 定义

分布式事务的原子性要求跨多个节点或服务的操作集合,如同单机事务一样,具备 “要么全做,要么全不做” 的特性。在微服务架构中,一个订单创建事务可能涉及订单服务创建订单记录、库存服务扣减库存、支付服务处理支付,这些操作必须整体成功或失败,否则会出现订单生成但库存未扣减、已支付却无订单记录等数据混乱情况 。

4.2 归纳演绎

我们先不管市面上的分布式事务解决方案,我们来一步一步仔细推演思考下,如果是我们自己来设计,我们会如何做。

①不可靠的网络——确认应答模式&重试机制

首先,我们需要问自己一个问题,在分布式环境中我们如何解决网络的不可靠问题的?

具体点,针对一次rpc请求,我们如何确保本次请求是成功的?

参考TCP中可靠传输机制,其实我们很容易发现,我们很多分布式的机制,都是基于请求-应答机制来保证网络的可靠性的。

这个也很好理解,在我们生活中,我们打招呼时,只有对方应答了,我们才能确认对方是听到我们的说话了。

但如果对方没听到,我们如何保证对方能够听到呢?

当然是重新打招呼呀!

对应到我们的问题,当服务提供方没有响应时,我们如何保证请求的可靠呢,方法只有一个——就是重试

基于确认应答模式重试机制,我们可以像搭积木一样开始设计我们的方案。

②二阶段提交(2PC):要么全做,要么全不做

回顾下我们的目标,我们的目标是在多节点的情况下,实现多节点上的操作要么一起成功,要么一起失败。

如何判断我们的操作成功了呢?

我们很自然能够想到,

我们可以对所有节点发送操作请求,如果所有请求返回成功了,那么就是整体成功了。

如果有其中任一节点失败了,那么整体的操作就应该一起失败。

怎么一起失败,就是把所有节点执行回滚操作。

而这就是**二阶段提交(2PC)**的雏形!

在这里插入图片描述

③TCC 模式:业务场景的2PC

TCC(Try - Confirm - Cancel)和 2PC 思路类似,把操作拆成三步:

  • Try:尝试预留资源,比如预订酒店先锁定房间但不扣款;
  • Confirm:确认提交,真正扣款并占用资源;
  • Cancel:如果 Try 或 Confirm 失败,释放预留资源,比如取消房间预订。

每个阶段都靠确认应答确认成功,失败就重试或回滚,确保事务完整。

④三阶段提交(3PC):减少等待,预防卡死

2PC 有个问题:如果协调者在第二阶段崩溃,节点可能一直等待,导致系统卡住。3PC 加了一个预提交阶段,就像聚会前先和大家确认 “时间地点没问题吧?”,提前排除潜在问题。这样即便协调者中途出故障,节点也能根据预提交结果,更自主地决定提交或回滚,减少阻塞。

本质是增加环节,减少占用实际资源的时间,减少阻塞。

⑤回滚操作的灵魂拷问

Mysql为什么能够回滚?

在Mysql中,因为写操作会占有行锁,这意味着在事务提交前,该数据行的写操作是串行化的,这就避免数据竞态条件竞争的问题。

同时通过redo log事务日志,我们可以回溯到之前的数据版本,使我们回滚操作成了可能。

锁机制事务日志使Mysql可以正确的进行回滚操作。

可以不回滚吗?

答案是可以!

审一下题目,目标是要么全部成功,要么全部失败。

那么我只要保证都成功,就不会有失败,这样就可以实现一样的效果。

⑥消息队列实现的思考——尽最大努力交付

这里我们可以参考消息队列实现。

消息队列的消息消费,支持至少消费一次,那消息队列是如何实现的呢?

答案就是我们在开头说的 重试 !通过不断的重试来保证消息最终的到达。

这也是为什么消息消费逻辑要支持幂等。

重试也有讲究,如何优雅的重试?

比如消息队列会设计重试间隔时间,基于短时间无法恢复的基础,会有重试间隔的设计。

重试次数也有讲究,不可能一直无限重试下去,所以会有死信队列的设计。

那我们如何实现事务呢,就是重试!

所以,在异步场景下,我们很多方案都是通过消息队列来实现最终的一致性,保证全部成功。

消息队列 消费者 死信队列 发送消息 告知消息处理失败 等待重试(设置重试间隔) 重新发送消息 loop [消息处理失败且未达到最大重- 试次数] 转移消息 确认接收消息 确认消息已消费 确认成功 alt [达到最大重试次数] [消息处理成功] 消息队列 消费者 死信队列

⑦消息队列发送如何保障一致性

mq消费能实现最终一致性,但是针对于业务服务来说,消息队列发送消息也是一次网络通信,也可能会出现不一致的问题。

所以我们需要保证消息队列的一致性问题

本地消息表

本地消息表是一种通过在本地数据库中记录消息状态来保障消息发送一致性的方法。

其核心思想是将消息的发送与本地事务绑定,通过定时任务或其他机制来确保消息最终能够成功发送到消息队列。

应用系统 本地数据库 消息队列 定时任务 开启本地事务 执行本地业务操作(如订单创建) 插入消息记录(消息内容、状态等) 本地事务提交成功 查询状态为未发送的消息 返回未发送的消息列表 发送消息 消息发送成功,返回确认信息 更新消息状态为已发送 更新成功 loop [遍历消息列表] 应用系统 本地数据库 消息队列 定时任务

在这个过程中,应用系统在执行本地业务操作后,将相关消息记录插入本地数据库,并提交本地事务。定时任务会定期查询本地数据库中状态为未发送的消息,并尝试将其发送到消息队列。当消息发送成功后,定时任务会更新消息在本地数据库中的状态为已发送。

本质还是重试的思路,用定时任务重试发送失败的消息。

事务消息

事务消息是一种借助消息队列自身特性来保障消息发送一致性的方式。它通常基于消息队列提供的半事务消息机制,确保本地事务和消息发送的原子性。

应用系统 消息队列 本地数据库 发送半事务消息(消息内容、回调信息等) 半事务消息发送成功,消息状态为暂存 开启本地事务 执行本地业务操作(如订单创建) 确认发送消息 消息确认发送成功 回滚消息 消息回滚成功 alt [本地事务成功] [本地事务失败] 应用系统 消息队列 本地数据库

应用系统首先向消息队列发送半事务消息,消息队列接收到消息后将其状态设置为暂存,并返回成功响应。然后应用系统开启本地事务并执行本地业务操作。如果本地事务成功,应用系统向消息队列确认发送消息;如果本地事务失败,应用系统则向消息队列回滚消息。消息队列根据应用系统的指令进行相应的操作,确保消息发送与本地事务的一致性。

这种方式和2PC类似,都是基于**prepare - commit **的思路。

只不过两者角度不同,2PC针对多节点的事务操作;事务消息保障的是本地事务和发送消息操作之间的事务操作。

4.3 原子性问题解决范式

原子性的解决思路大致分为两类:

  • 回滚:当事务中任何一个操作失败时,通过补偿机制撤销已成功执行的操作,将系统状态恢复到事务开始前。
    • 回滚,一般针对数据库说的
    • 补偿,一般针对业务场景
  • 最大努力交付:优先保证事务中尽可能多的操作能够成功执行,即使部分操作失败,也让系统处于相对可用的状态。

怎么实现呢,万变不离其宗,核心都是通过 确认应答模式 拉齐认知,利用重试机制 进行可靠性兜底。

4.4 思考——分布式事务的优与劣

4.4.1 优势:支撑复杂业务的基石
  1. 业务扩展性强:在互联网电商大促场景下,订单创建、库存扣减、支付处理等操作分布在不同微服务节点,分布式事务的原子性确保各环节要么共同完成,要么全部回滚。以双十一大促为例,即便每秒数万笔订单并发,也能避免超卖、资金错配等问题,保障业务顺利开展。
  2. 数据一致性保障:在金融分布式账本系统中,跨地域的转账交易涉及多个节点数据更新,通过分布式事务方案(如2PC),确保转出账户扣款与转入账户到账操作同步,避免资金凭空增减,维护金融数据的精准性。
  3. 高可用架构支撑:采用分布式事务的系统可通过多节点部署实现负载均衡与故障转移。当某节点出现故障时,其他节点可继续参与事务处理,如分布式数据库集群中,部分节点宕机不影响整体事务的原子性,维持系统服务的连续性 。
4.4.2 劣势:性能与复杂度的双重挑战
  1. 性能损耗显著:2PC、3PC等协议在协调多节点时,需多次网络通信与等待确认,引入额外延迟。例如在高并发订单场景中,2PC的两阶段确认过程可能使订单处理响应时间增加数倍,影响用户体验。
    在这里插入图片描述

  2. 系统复杂度激增:分布式事务涉及协调者、参与者、消息传递等多个组件,故障排查困难。以TCC模式为例,每个服务需实现Try、Confirm、Cancel三个阶段逻辑,且需处理网络超时、事务回滚等异常,增加开发与维护成本。

  3. 资源消耗大:为保证原子性,锁机制(如分布式锁)会占用大量资源,降低系统并发能力。在秒杀活动中,大量事务竞争锁资源,可能导致部分请求长时间等待,甚至超时失败,影响业务吞吐量。

  4. 网络依赖风险:由于依赖网络通信实现节点间协调,不可靠网络会放大事务失败概率。例如网络分区导致节点间无法通信,可能使2PC陷入阻塞,3PC也难以完全规避此类问题,威胁系统稳定性。

4.5 实现场景

4.5.1 OceanBase(2PC)

OceanBase 数据库实现了原生的两阶段提交协议,保证分布式事务的原子性。

两阶段提交协议中包含两种角色,协调者(Coordinator)和参与者(Participant)。协调者负责整个协议的推进,使得多个参与者最终达到一致的决议。参与者响应协调者的请求,根据协调者的请求完成 prepare 操作及 commit/abort 操作。

在这里插入图片描述

PREPARE 阶段

协调者:协调者向所有的参与者发起 prepare request

参与者:参与者收到 prepare request 之后,决定是否可以提交,如果可以则持久化 prepare log 并且向协调者返回 prepare 成功,否则返回 prepare 失败。

COMMIT阶段

协调者:协调者收齐所有参与者的 prepare ack 之后,进入 COMMIT 状态,向用户返回事务 commit 成功,然后向所有参与者发送事务 commit request。

参与者:参与者收到 commit request 之后释放资源解行锁,然后提交 commit log,日志持久化完成之后给协调者回复commit ok消息,最后释放事务上下文并退出。

4.5.2 Seata框架——业务框架

Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案框架,提供了AT、TCC、Saga等多种事务模式,可适配不同业务场景需求,尤其适用于微服务架构下的复杂业务逻辑。

以AT(自动补偿)模式为例,它对业务代码的侵入性较低。在执行事务时,Seata会自动对业务数据进行快照保存,执行本地事务操作后,将操作记录和快照信息上报给事务协调器TC(Transaction Coordinator)。当事务需要回滚时,根据快照和操作记录自动生成反向SQL,恢复数据到事务开始前的状态。在电商订单场景中,涉及订单服务、库存服务、支付服务等多个微服务,Seata能确保这些服务的操作在分布式环境下满足原子性要求,同时通过模块化设计降低开发和维护成本,开发者只需关注业务逻辑,无需手动编写复杂的事务补偿代码。

在这里插入图片描述
在这里插入图片描述

AT 模式本质是回滚,通过 全局锁+自动生成的反向SQL 实现回滚操作。

4.5.3 QMQ——本地消息表实现

QMQ(Quantum Message Queue)是去哪儿网自主研发的分布式消息队列,在保障消息一致性方面采用本地消息表方案。在业务系统执行本地事务(如订单创建)时,会同时将消息相关信息(消息内容、状态等)插入到本地数据库的消息表中,确保消息与本地事务的原子性。

随后,QMQ通过定时任务或异步线程扫描消息表,将状态为“未发送”的消息发送到消息队列。当消息成功发送后,更新消息表中的状态为“已发送”;若发送失败,则继续重试。这种方式简单可靠,适用于对一致性要求较高且业务逻辑相对简单的场景,如电商系统中订单状态变更通知、物流信息推送等。通过本地消息表,QMQ实现了业务操作与消息发送的最终一致性,同时降低了系统的耦合度。

4.5.4 Rocketmq——事务消息

RocketMQ是一款分布式消息中间件,其事务消息功能基于半事务消息机制,确保本地事务与消息发送的原子性,适用于分布式事务场景中的异步解耦与最终一致性保障。

在发送事务消息时,生产者先向RocketMQ发送半事务消息,此时消息对消费者不可见;接着执行本地事务,根据事务执行结果向RocketMQ发送提交或回滚请求。若本地事务成功,RocketMQ将消息标记为可消费,消费者接收并处理消息;若本地事务失败,RocketMQ删除半事务消息,避免无效消息被消费。(本质是二阶段提交)

兜底情况通过定时任务回查实现。(本质是重试

在这里插入图片描述

五、隔离性

常见场景

在分布式环境中,事务隔离性面临更多挑战,一些典型问题严重影响数据一致性。

以下列举几种业务中常见的因为隔离性产生的问题:

  • 主从延迟:在主从数据库架构下,主库数据更新后同步到从库存在时间差。若应用在同步完成前从从库读取数据,可能获取到旧值,导致数据不一致。例如电商商品价格在主库修改后,从库因延迟未及时更新,用户查询时看到的仍是旧价格 。
  • mq 消费反查查询到旧值:通过消息队列(MQ)进行数据同步时,消费者接收到消息后进行业务处理,若处理过程中需要反查数据库确认数据状态,可能因数据库更新不及时查到旧值,进而导致业务逻辑错误。如订单状态变更消息发送到 MQ,消费者处理时反查数据库,却因数据库同步延迟获取到未更新的状态 。

解决思路

和单机事务类似,只不过分布式环境更为复杂。

  1. 读屏障
    1. 强制读主,避免多节点读
      比如业务操作中,我们常会提供主库查询接口用于某些一致性要求高的场景
    2. 分布式快照读,该方案常见于数据库,和单机事务类似,唯一不同就是需要解决分布式的事务id问题
      以蚂蚁的分布式数据库OceanBase为例,它利用分布式共识算法维护的全局时间戳(解决不可靠的时钟问题)来定义快照版本,根据事务隔离级别来决定读取对应的数据快照。
  2. 使用锁机制控制并发:本质是细粒度维度(如数据行、数据范围)去串行化写操作,来保证数据写的正确性

就隔离性而言,分布式环境 和单机环境基本一致,不过需要考虑 多副本数据的读写规则,来实现对外的一致性。本质其实冗余数据存储场景下的数据一致性问题,详细的可以看本系列的第一篇文章,数据一致性问题剖析与实践(一)——冗余数据存储&分布式共识决策中的一致性问题。

六、持久性

定义

分布式事务的持久性指事务提交后,其产生的数据变更在分布式环境下的多个节点或存储介质中,都能可靠持久保存,不会因节点故障、网络分区等问题丢失。在分布式数据库集群中,数据写入成功提交后,无论哪个节点出现故障,数据都应可恢复且保持一致 。

解决范式

  • 持久化存储,避免数据丢失:采用多副本存储、日志持久化等技术保障数据持久性。分布式数据库通过将数据同步复制到多个节点,即使个别节点故障,其他副本仍可提供数据服务;同时,事务操作日志会持久化记录到磁盘,用于故障恢复时重做或回滚事务,确保数据不丢失、事务可恢复 。
  • 副本存储,异地容灾

七、总结

分布式事务和单机事务非常类似,都需要去实现ACID特性。

只不过,在分布式环境中,由于不可靠的网络和时钟,导致我们需要通过确认应答模式&重试机制来增加一些机制来实现 事务的原子性。

由于这些额外的机制,会导致性能的急剧下滑(全局锁&重试),所以我们常常为了平衡,会根据自己的业务场景去决策实现哪种程度的一致性(强一致性/顺序一致性/最终一致性)。

所以考虑到分布式事务的高昂成本,常规的设计思路应是:

1.思考当前场景是否需要分布式事务,如果不需要,则尽量避免,比如 商品库存和库存流水常常都在一个领域操作内,我们就尽量设计在一个库中,因为此时本地事务就可以解决,不需要分布式事务

2.如果实在需要分布式事务,思考几个问题

  • 思考业务可以容忍的场景,是强一致性,还是最终一致性?
  • 思考业务逻辑是否可以回滚,是否支持补偿?
  • 思考业务逻辑之间的依赖,是异步执行还是同步执行?

3.根据公司已有的基建选择合适(成本低)的方案

  • 回滚
    • 前提:业务支持回滚/补偿
    • 适用场景:
      • 强一致性
      • 支持回滚/补偿
      • 同步执行
    • 2PC、3PC
    • TCC
  • 尽最大努力交付
    • 前提:业务异步执行
    • 适用场景:
      • 最终一致性
      • 异步执行
    • 消息队列
      • 本地消息表
      • 事务消息

从模型领域设计上来讲,理想的领域交互,应该是通过事件机制,通过类似消息队列去实现事件的异步扩散,实现模型之间的最终一致性。

此上,如有不对的地方,欢迎指正。

参考文档

OceanBase两阶段提交
设计数据密集型应用 - 中文翻译
漫谈分布式共识算法与数据一致性
RocketMQ事务消息

相关文章:

  • Spring Boot中的监视器:Actuator的原理、功能与应用
  • JavaScript 防抖和节流
  • JavaFX 第一篇 Hello World
  • 在线测试来料公差
  • 【开源】STM32HAL库移植Arduino OneWire库驱动DS18B20和MAX31850
  • 香港科技大学广州|先进材料学域博士招生宣讲会—南开大学专场
  • OpenCV 图形API(54)颜色空间转换-----将图像从 RGB 色彩空间转换到 HSV色彩空间RGB2HSV()
  • day001
  • 计算机网络笔记(七)——1.7计算机网络体系结构
  • 无穿戴动捕:突破穿戴式设备束缚,解锁更自由高效的动作捕捉体验
  • Linux/AndroidOS中进程间的通信线程间的同步 - IPC方式简介
  • 智能配送机器人控制系统设计
  • MySQL 8.4企业版 安装和配置审计插件
  • 0422--在网页中上传头像(图片)
  • ChatBEV:一种理解 BEV 地图的可视化语言模型
  • 【论文阅读25】-滑坡时间预测-PFTF
  • 解耦旧系统的利器:Java 中的适配器模式(Adapter Pattern)实战解析
  • bert4keras
  • UV: Python包和项目管理器(从入门到不放弃教程)
  • SQL 时间转换的CONVERT()函数应用说明
  • 停止水资源共享、驱逐武官,印度对巴基斯坦宣布多项反制措施
  • 魔都眼·上海车展②|小鹏汽车:何小鹏携手机器人车模首秀
  • 杨国荣丨《儒耶对话与中国现代思想的生成和发展》序
  • 安徽临泉一小区交付后多楼层现裂缝,专家组论证称不影响安全
  • 世界读书日丨人均一年超10本!你达到上海平均阅读水平了吗
  • 中国驻日本大使馆发言人就日方涉靖国神社消极动向答记者问