Leaf生成分布式ID的原理?

典型回答 Leaf是美团的分布式ID框架,他有2种生成ID的模式,分别是Snowflake和Segment。 在Segment(号段)模式中,他的意思就是每次去数据库中取ID的时候取出来一批,并放在缓存中,然后下一次生成新ID的时候就从缓存中取。这一批用完了再去数据库中拿新的。 而为了防止多个实例之间发生冲突,需要采用号段的方式,即给每个客户端发放的时候按号段分开,如客户端A取的号段是1-1000,客户端B取的是1001-2000,客户端C取的是2001-3000。当客户端A用完之后,再来取的时候取到的是3001-4000。 号段模式的好处是在同一个客户端中,生成的ID是顺序递增的。并且不需要频繁的访问数据库,也能提升获取ID的性能。 这种模式的优点是,虽然依赖数据库,但是因为有号段缓存,所以在数据库宕机后的一段时间内也能保证可用性,并且这种模式不依赖时钟,所以不存在时钟回拨的问题。 缺点也比较明显,首先是如果多个缓存中刚好用完了号段,同时去请求数据库获取新的号段时可能会导致并发争抢影响性能,另外,DB如果宕机时间过长,缓存中号段耗尽也会有可用性问题。 为了解决多个号段用完之后取新的号段冲突,Leaf还引入了双buff,当号段消费到某个阈值时就异步的把下一个号段加载到内存中,而不需要等到耗尽才去更新,这样可以避免取号段的时候导致没有号码分配影响可用性及性能。 在Snowflake模式中,当然是基于Twitter的Snowflake算法实现的了。但是主要是针对Snowflake中存在的一些问题做了很多优化。 相对于Snowflake,Leaf 在以下几个方面进行了优化: 数据中心ID和机器ID的配置方式:Snowflake需要在代码中硬编码数据中心ID和机器ID,而Leaf通过配置文件的方式进行配置,可以动态配置数据中心ID和机器ID,降低了配置的难度。 引入区间概念:Leaf引入了区间的概念,每次从zookeeper获取一段ID的数量(比如1万个),之后在这个区间内产生ID,避免了每次获取ID都要去zookeeper中获取,减轻了对zookeeper的压力,并且也可以减少对ZK的依赖,并且也能提升生成ID的效率。 自适应调整:Leaf支持自适应调整ID生成器的参数,比如每个区间的ID数量、ID生成器的工作线程数量等,可以根据实际情况进行动态调整,提高了系统的性能和灵活性。 支持多种语言:Leaf不仅提供了Java版本的ID生成器,还提供了Python和Go语言的版本,可以满足不同语言的开发需求。 时钟回拨解决:每个 Leaf 运行时定时向 zk 上报时间戳。每次 Leaf 服务启动时,先校验本机时间与上次发 ID 的时间,再校验与 zk 上所有节点的平均时间戳。如果任何一个阶段有异常,那么就启动失败报警。 Leaf的分布式ID生成过程可以简述如下: Leaf生成器启动时,会从配置文件中读取配置信息,包括数据中心ID、机器ID等。 Leaf生成器会向zookeeper注册自己的信息,包括IP地址、端口号等。 应用程序需要生成一个ID时,会向Leaf生成器发送一个请求。 Leaf生成器会从zookeeper中读取可用的区间信息,并分配一批ID。 Leaf生成器将分配的ID返回给应用程序。 应用程序可以使用返回的ID生成具体的业务ID。 当分配的ID用完后,Leaf生成器会再次向zookeeper请求新的区间。

March 22, 2026 · 1 min · santu

Redis 的分布式锁和 Zookeeper 的分布式锁有啥区别?

典型回答 在分布式锁的实现方案中,通常就是数据库、Redis 以及 Zookeeper 这三种,关于分布式锁的多种实现方式及原理我们这里不展开了,文档中已经有很多了,大家可以搜索下即可。 本文主要聚焦 Redis 的分布式锁和Zookeeper 的分布式锁之间的区别,以及如何选择。 其实在功能上,Redis 的分布式锁和 ZK 的分布式锁都能实现我们想要的功能,锁的互斥、重入等等。他们主要有以下几个区别: 性能区别 在性能方面,Redis 是基于内存存储的,而 ZK 是基于磁盘存储的,所以,在性能上,Redis 要比 ZK 更好一些。 自动释放 ZK 的锁的实现原理是基于客户端和服务端的连接来保证的,一旦连接断了,锁就会被自动释放。而 Redis 的锁是需要自己主动加锁和解锁的,除非达到了超时时间,否则不会自动释放。 所以,ZK 的分布式锁可以更好的应对客户端崩溃的情况,一旦客户端崩溃,锁就会释放,而 Redis 实现的分布式锁,一旦客户端崩溃了,就没有人去进行释放了,只能等超时。 锁能自动释放有啥好处?除了提升并发度意外,还有个好处就是可以减少死锁发生的概率。因为锁释放了,所以就不会出现死锁了。 一致性&可用性要求(CAP) 我们分别介绍过关于 Redis和 Zookeeper 的 CAP 的实现情况,我们知道ZK 是一个 CP 的系统,也就是他是保证强一致性的,而 Redis 是一个 AP 的系统,它是保证可用性的。 ✅Zookeeper是CP的还是AP的? ✅Redis是AP的还是CP的? ZK 会牺牲可用性来保证数据的一致性,即出现部分节点宕机后,集群中少于一半的节点后,或者集群正在进行 master 选举是,都会拒绝新的写请求,导致无法加锁。 而 Redis 会牺牲一致性性来保证可用性,即 Redis 的集群中在做数据同步时,如果出现网络延迟,那么即使多个节点上面的数据不一样,客户端也可以正常的进行写入和读取。 那么,在使用 ZK 的分布式锁的时候,不会存在锁丢失的情况,也就是说不太会出现因为锁丢失而导致并发的情况。但是,可能会出现短暂的无法加锁的情况。 而在使用 Redis 的分布式锁的时候,除非集群都挂了,要不然不太会出现无法加锁的情况。但是可能会出现锁丢失的情况,或者说是重复加锁的情况,我们介绍 RedLock 的时候提到的单点故障的问题: ✅什么是RedLock,他解决了什么问题? 做个总结 Redis 实现的分布式锁、性能更好,可用性更高。ZK 实现的分布式锁可以自动释放,减少死锁出现的概率,并且他的一致性更有保障。 ...

March 22, 2026 · 1 min · santu

Seata的AT模式会不会出现脏读?为什么?

典型回答 一句话回答:会出现一种脏读情况,只不过和传统脏读不一样,传统的脏读指的是读取到其他(MySQL本地事务)事务未提交的数据。而Seata会出现,读取到其他(分支事务)(本地事务)事务已提交但可能被全局回滚的数据。 (听上去有点绕?你看完下面的介绍在回过头来看,就能明白了。。。) 想要回答好这个问题,需要先了解一下Seata的AT模式的工作原理。 ✅Seata的AT模式的实现原理 上面这篇很详细的介绍了原理,这里我们简单总结下,把其中关键点单独拿出来说一下。 AT模式的核心机制是两阶段提交: 第一阶段:本地事务立即提交,释放本地锁,数据对其他事务可见。 第二阶段:全局事务根据协调结果决定提交或回滚(通过undo log补偿)。 那么,大家仔细想一下这个场景,其实会出现一种情况,那就是如果全局事务最终回滚,其他事务可能在P第一阶段结束后、第二阶段回滚前读取到**已提交但即将被撤销的数据**,导致**逻辑上的脏读**。 举个例子。 现在有三个模块,交易模块、订单模块和库存模块。在一次下单过程中,为了保证一致性,代码可能如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Service public class TradeService{ @Autowired private InventoryService inventoryService; @Autowired private OrderService orderService; @GlobalTransactional public boolean buy(){ //库存扣减 inventoryService.decreaseInvenroty(); //创建订单 orderService.createOrder(); } } 在这个分布式事务中(@GlobalTransactional开启的分布式事务),先调库存服务进行库存扣减,然后再调用订单服务进行订单创建。那么整个(大致)流程就是这样的: ...

March 22, 2026 · 1 min · santu

Seata的AT模式和XA有什么区别?

典型回答 XA是一个典型的分布式事务解决方案,是一个强一致性模型,基于XA的2PC和3PC一直都是业内比较成熟的分布式方案,但是,他们都存在着各种各样的问题。 Seata中的AT模式其实和2PC很像,都是把一个分布式事务分成了2个阶段,那他们之间有什么区别呢? 主要区别就是在一阶段和二阶段做的事情上。 AT XA 1阶段 各个分支事务正常执行并提交,并记录日志,这些日志可以用来在二阶段进行回滚 各个分支事务执行预提交操作,数据库锁定资源但不实际提交。 2阶段 如果需要回滚,系统根据UNDO日志来恢复到一阶段操作前的状态。如果需要提交,直接结束即可,因为一阶段已经完成实际的数据库操作。 如果协调器决定提交事务,所有参与者提交预提交的操作。如果决定回滚,则所有参与者撤销预提交的操作。 所以,他们的主要区别就在于一阶段是否直接提交事务,Seata的AT模式中,为了提升性能,直接提交了事务,在二阶段,需要回滚的话再执行回滚。而XA中,一阶段是只做资源占用,二阶段在进行回滚或者提交。 所以,AT的性能是明显高于XA的,因为在一阶段已经执行了实际的数据库操作,并不需要做资源的占用和锁定,而二阶段也只是在失败的情况下再执行回滚,所以性能相对较高。 而XA这种模式由于需要锁定资源直到二阶段结束,对数据库性能有较大影响,尤其在高并发环境下。 而在一致性方面,XA确实要比AT好的,因为在一阶段所有参与者都只进行预提交操作,二阶段再根据协调器的决定进行实际提交或回滚,确保了全局事务的一致性。 而AT这种模式,一阶段是做了数据提交的,提交后就可能被其他事物看到,那么就会出现事务被提前看到的情况。所以会存在短暂的不一致。 所以总结一下: AT XA 性能 高 低 一致性 最终一致性 强一致性 适用场景 高吞吐量场景 高一致性要求场景,如资金、金融 复杂度 借助Seata无侵入性实现 高

March 22, 2026 · 1 min · santu

Seata的AT模式的实现原理

典型回答 Seata 是一个开源的分布式事务解决方案,旨在提供高性能和简单的事务管理服务,用于微服务架构。其中,AT 模式是 Seata 支持的一种事务模式,全称为 Auto-Commit Transaction,也就是自动提交事务模式。 它是一种无侵入性的事务模式,对于业务开发来说,不需要做代码上面的改造,就可以实现分布式事务。 Seata中包含了三个组件: TC (Transaction Coordinator):事务协调器,负责管理全局事务的生命周期,包括开始事务、提交事务和回滚事务。 TM (Transaction Manager):事务管理器,定义事务的范围,负责开启和结束全局事务。 RM (Resource Manager):资源管理器,管理资源对象,如数据库连接,负责资源的注册与释放。 详见: ✅什么是Seata?他有哪几种模式? AT 模式基于两阶段提交(2PC)协议进行工作,通过代理数据源的方式,使得本地事务(如数据库事务)与全局事务(跨服务的事务)能够统一管理。 所谓代理数据源,其实就是在应用自己的Datasource之上做了一层代理,使得原本的JDBC Datasource变成Seata DatasourceProxy,这样就可以在这层代理当中控制SQL语句的提交、回滚等操作。 在Seata的AT模式中,事务的提交也是分成了2阶段的。 一阶段 1、RM针对本次要执行的本地事务的SQL进行解析,得到SQL的类型、修改的表以及where条件等信息。 2、RM 根据 SQL 解析的结果,先进行一次查询,根据查询结果生成相应的 before image(变更前数据快照)。 3、执行SQL语句进行数据库变更。 4、再查询一次变更后的记录,作为after image(变更后的数据快照) 5、把before/after image 以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。 6、提交前,向 TC 注册分支,并申请表中本次需要修改的所有记录的排他锁。 7、将业务数据的更新和前面生成的 UNDO LOG 一并提交。 8、将本地事务的执行结果上报给TC。 这里依赖的完全是本地事务,基于本地事务的ACID的特性,可以保证业务数据和回滚日志(before/after image)可以在同一个本地事务中被提交。 二阶段 在一阶段,业务操作完成后,TM 向 TC 发起提交请求。TC 会发起投票请求,询问所有的RM是否可以提交事务。 那么就会出现2种情况: 提交事务:如果所有的 RM 都同意提交,说明他们此时他们的本地事务都已经执行成功了,那么TC就可以释放该全局事务的所有锁,然后异步调用RM清理Undo Log 回滚事务:如果任一 RM 投票否决或者出现故障,那么就要协调事务进行回滚。 ...

March 22, 2026 · 2 min · santu

Seata的实现原理是什么

典型回答 Seata是一个阿里开源的分布式事务解决方案(Simple Extensible Autonomous Transaction Architecture),用于在分布式系统中实现分布式事务。它旨在简化分布式事务的开发和管理,帮助解决分布式系统中的数据一致性问题。 因为Seata的开发者坚定地认为:一个分布式事务是有若干个本地事务组成的。所以他们给Seata体系的所有组件定义成了三种,分别是Transaction Coordinator、Transaction Manager和Resource Manager Transaction Coordinator(TC): 这是一个独立的服务,是一个独立的 JVM 进程,里面不包含任何业务代码,它的主要职责:维护着整个事务的全局状态,负责通知 RM 执行回滚或提交; Transaction Manager(TM): 在微服务架构中可对应为聚合服务,即将不同的微服务组合起来成一个完整的业务流程,TM 的职责是开启一个全局事务或者提交或回滚一个全局事务; Resource Manager(RM):RM 在微服务框架中对应具体的某个微服务为事务的分支,RM 的职责是:执行每个事务分支的操作。 看上去好像很难理解?举个例子你就知道了: 在一个下单事务中,我们有一个聚合的服务,姑且把他叫做TradeCenter吧,他负责接收并处理用户的下单请求,并且下单过程中需要调用订单服务(Order)、库存服务(Stock)及账户服务(Account)进行创建订单、扣减库存及增加积分。 所以TradeCenter担当的就是TM的角色,而Order、Stock及Account三个微服务就是RM的角色。在此之外,还需要一个独立的服务,维护分布式事务的全局状态,他就是TC。 因为TC维护着整个事务的全局状态,负责通知 RM 执行回滚或提交,所以他和TM、RM都是有交互的。并且TM和RM之间也有调用关系。多个RM之间可以是独立的。 上面这个场景中,要想保证分布式事务,就需要Order、Stock及Account三个服务对应的数据库表操作,要么都成功、要么都失败。不能有部分成功、部分失败的情况。 在用了Seata之后,一次分布式事务的大致流程如下(不同的模式略有不同,在介绍具体模式的时候分别展开): 1、TM在接收到用户的下单请求后,会先调用TC创建一个全局事务,并且从TC获取到他生成的XID。 2、TM开始通过RPC/Restful调用各个RM,调用过程中需要把XID同时传递过去。 3、RM通过其接收到的XID,将其所管理的资源且被该调用所使用到的资源注册为一个事务分支(Branch Transaction) 4、当该请求的调用链全部结束时,TM根据本次调用是否有失败的情况,如果所有调用都成功,则决议Commit,如果有超时或者失败,则决议Rollback。 5、TM将事务的决议结果通知TC,TC将协调所有RM进行事务的二阶段动作,该回滚回滚,该提交提交。 这里要求所有的RM都能做到2阶段,第一阶段做事务的预处理,第二阶段做事务的提交或者回滚。具体怎么实现,是否需要自己改代码,这个不同的模式不太一样。 扩展知识 Seata 的四种事务模式 ✅Seata的4种事务模式,各自适合的场景是什么?

March 22, 2026 · 1 min · santu

TCC的空回滚和悬挂是什么?如何解决?

典型回答 TCC是一种分布式的事务的方案,将一个事务分成了TRY-CANCEL-CONFIRM三个阶段: ✅什么是TCC,和2PC有什么区别? 在TCC中,存在着两个比较关键的问题,那就是空回滚和悬挂的问题。 空回滚问题:TCC中的Try过程中,有的参与者成功了,有的参与者失败了,这时候就需要所有参与者都执行Cancel,这时候,对于那些没有Try成功的参与者来说,本次回滚就是一次空回滚。需要在业务中做好对空回滚的识别和处理,否则就会出现异常报错的情况,甚至可能导致Cancel一直失败,最终导致整个分布式事务失败。 悬挂事务问题:TCC的实现方式存在悬挂事务的问题,在调用TCC服务的一阶段Try操作时,可能会出现因网络拥堵而导致的超时,此时事务协调器会触发二阶段回滚,调用TCC服务的Cancel操作;在此之后,拥堵在网络上的一阶段Try数据包被TCC服务收到,出现了二阶段Cancel请求比一阶段Try请求先执行的情况。举一个比较常见的具体场景:一次分布式事务,先发生了Try,但是因为有的节点失败,又发生了Cancel,而下游的某个节点因为网络延迟导致先接到了Cancel,在空回滚完成后,又接到了Try的请求,然后执行了,这就会导致这个节点的Try占用的资源无法释放,也没人会再来处理了,就会导致了事务悬挂。 这两个问题处理不好,都可能会导致一个分布式事务没办法保证最终一致性。有一个办法,可以一次性的解决以上两个问题,那就是——引入分布式事务记录表。 有了这张表,每一个参与者,都可以在本地事务执行的过程中,同时记录一次分布式事务的操作记录。 这张表中有两个关键的字段,一个是tx_id用于保存本次处理的事务ID,还有一个就是state,用于记录本次事务的执行状态。至于其他的字段,比如一些业务数据,执行时间、业务场景啥的,就自己想记录上就记录啥。 1 2 3 4 5 CREATE TABLE `distribute_transaction` ( `tx_id` varchar(128) NOT NULL COMMENT '事务id', `state` int(1) DEFAULT NULL COMMENT '事务状态,0:try,1:confirm,2:cancel', PRIMARY KEY (`tx_id`) U ) 有了这张表以后,我们在做try、cancel和confirm操作之后,都需要在本地事务中创建或者修改这条记录。一条记录的状态机如下: 空回滚解决:当一个参与者接到一次Cancel请求的时候,先去distribute_transaction表中根据tx_id查询是否有try的记录,如果没有,则进行一次空回滚即可。并在distribute_transaction中创建一条记录,状态标记为cancel。 事务悬挂解决:当一个参与者接到一次Try请求的时候,先去distribute_transaction表中根据tx_id查询是否有记录,如果当前存在,并且记录的状态是cancel,则拒绝本次try请求或者直接返回try成功即可。 但是需要注意的是,上面的请求过程,需要做好并发控制。 有了这张表,我们还可以基于他做幂等控制,每次try-cancel-confirm请求来的时候,都可以到这张表中查一下,然后做幂等控制。

March 22, 2026 · 1 min · santu

什么是CAP理论,为什么不能同时满足?

典型回答 CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。 网上有很多关于CAP的介绍,其中关于一致性、可用性及分区容错性的介绍也有很多,但是这里需要重新纠正一下CAP中这三个特性的意思(https://en.wikipedia.org/wiki/CAP_theorem ): 一致性 每次读取都会收到最新的写入数据或错误信息。 可用性 每个请求都会收到(非错误的)响应,但不能保证响应包含最新的写入数据。 分区容忍性 尽管网络节点之间会丢弃(或延迟)任意数量的消息,系统仍然能够继续运行。 注意,可用性和分区容错性很多人都不会理解错误,但是一致性可能和大家认为的不太一样(甚至和网上99%讲CAP的文章都不一样)。 这里面的一致性,其实指的是强一致性,但是强一致性也并不是大家普遍认为的:“all nodes see the same data at the same time”,这只是其中一种情况,或者说是一种强一致性模型。 扩展知识 一致性模型 ✅什么是分布式系统的一致性? 在上文中,我们介绍过一致性模型中的强一致性其实有多种,包括了线性一致性、顺序一致性等,不同的分布式系统中,采取的强一致性模型并不一致,但是只要是其中的一种模型的实现,我们就可以认为这个系统是保证了一致性的。 如,Zookeeper保证的就是强一致模型中的顺序一致性而不是线性一致性。 ✅Zookeeper是CP的还是AP的? Availability 可用性 可用性指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。 对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。所以,一般我们在衡量一个系统的可用性的时候,都是通过停机时间来计算的。 可用性分类 可用水平(%) 年可容忍停机时间 容错可用性 99.9999 <1 min 极高可用性 99.999 <5 min 具有故障自动恢复能力的可用性 99.99 <53 min 高可用性 99.9 <8.8h 商品可用性 99 <3.65 d ...

March 22, 2026 · 1 min · santu

什么是OAuth2?有什么用?

典型回答 OAuth 2.0(OAuth2)是一种开放授权协议,它允许用户将有限的访问权限授权给第三方应用,而无需直接共享用户的凭据(如用户名和密码)。OAuth2 是目前最流行的授权框架之一,被广泛用于保护 API 和实现安全的访问控制。 以及单点登录的实现。 比如,我们可以通过 OAuth2 使用 微信、微博、QQ 等账号登录第三方应用,而不需要输入密码。 或者是我们可以用第三方应用来访问一些云端数据,如 Google Drive、Dropbox 。 下图是一个比较完成的OAuth2的流程,这里涉及到几个概念: 客户端(Client):第三方应用程序,如浏览器、APP等,希望访问一些特定的数据。 资源服务器(Resource Server):存储资源所有者的数据,并响应客户端的请求(如 API)。一般是指我们提供服务的后端服务器。 授权服务器(OAuth Server):负责验证资源所有者的身份并颁发令牌(Access Token)。 大致流程就是客户端先向授权服务器请求权限,权限校验通过后向客户端颁发一个令牌,即Access Token 后续客户端再访问资源服务器的时候,只需要带上这个令牌,资源服务器会对Access Token做验证,验证通过后则进行数据返回。 OAuth2的优点如下: 安全性:用户无需将密码提供给第三方应用,减少泄露风险。 灵活性:通过 Scope 定义访问权限范围。 普遍适用性:支持多种类型的客户端(Web 应用、移动应用、服务器端等)。 OAuth2的缺点如下: 实现复杂:授权流程和令牌管理机制较为复杂。 令牌保护:Access Token 暴露可能导致被滥用,因此需要结合 HTTPS、短时效性等机制加强安全。 授权服务器依赖:OAuth2 的安全性依赖于授权服务器的正确配置。

March 22, 2026 · 1 min · santu

什么是TCC,和2PC有什么区别?

典型回答 TCC是Try-Confirm-Cancel的缩写,它是一种分布式事务解决方案,采用了基于业务逻辑的补偿机制,将整个分布式事务分解为若干个子事务,每个子事务都有一个try、confirm和cancel三个操作,通过这些操作来实现分布式事务的执行和回滚 具体来说,TCC事务包括以下三个步骤: Try:在try阶段,参与者尝试执行本地事务,并对全局事务预留资源。如果try阶段执行成功,参与者会返回一个成功标识,否则会返回一个失败标识。 Confirm:如果所有参与者的try阶段都执行成功,则协调者通知所有参与者提交事务,那么就要执行confirm阶段,这时候参与者将在本地提交事务,并释放全局事务的资源。 Cancel:如果任何一个参与者在try阶段执行失败,则协调者通知所有参与者回滚事务。那么就要执行cancel阶段。 以下是一个简单的TCC事务的例子,假设有一个转账服务,需要从A账户中转移到B账户中100元、C账户中200元: Try阶段:转账服务首先尝试将A账户的金额冻结300元。 Confirm阶段:如果所有的try操作都执行成功,转账服务将尝试执行解冻并转账,将金额转到B账户和C账户中。 Cancel阶段:如果try过程中,某个转账事务执行失败。那么将执行解冻,将300元解冻。如果在confirm过程中,A->C的转账成功,但是A->B的转账失败,则再操作一次C->A的转账,将钱退回去。 TCC这种事务方案有以下优缺点: 优点: 灵活性:TCC适用于不同类型的业务场景,例如账户转账、库存扣减等,能够根据业务逻辑实现精细的事务控制。 高可用性:TCC使用分布式锁来保证分布式事务的一致性,即使其中一个节点出现故障,也不会影响整个系统的运行。 可扩展性:TCC采用分阶段提交的方式,支持横向扩展,可以适应更多的并发访问和业务场景。 性能:TCC相对于2PC来说,具有更好的性能表现 缺点: 实现复杂:TCC需要实现Try、Confirm和Cancel三个操作,每个操作都需要实现正确的业务逻辑和补偿机制,代码实现比较复杂。 存在悬挂事务问题:TCC的实现方式存在悬挂事务的问题,即在执行过程中可能会有部分子事务成功,而其他子事务失败,导致整个事务无法回滚或提交。 空回滚问题:TCC中的Try过程中,有的参与者成功了,有的参与者失败了,这时候就需要所有参与者都执行Cancel,这时候,对于那些没有Try成功的参与者来说,本次回滚就是一次空回滚。需要在业务中做好对空回滚的识别和处理,否则就会出现异常报错的情况,甚至可能导致Cancel一直失败,最终导致整个分布式事务失败。 业务代码侵入性:TCC需要将事务操作拆分为Try、Confirm和Cancel三个步骤,对业务代码有一定的侵入性,需要针对不同的业务场景进行实现。 ✅TCC的空回滚和悬挂是什么?如何解决? 扩展知识 Confirm/Cancel失败了怎么办? ✅TCC中,Confirm或者Cancel失败了怎么办? TCC和2PC有什么区别? 首先,二者的实现机制不同,2PC使用协调者和参与者的方式来实现分布式事务,而TCC采用分阶段提交的方式。 最大的区别:站在每一个事务的参与者角度看,TCC其实是把一个事务拆成了3个独立的事务,而2PC就只是一个事务。 TCC中,把一次业务操作,拆分成Try、Confirm、Cancel三个步骤,每一个步骤操作数据库的时候都是一个单独的事务,单独开启,单独提交。 2PC是一个事务,拆分成了准备阶段和提交阶段,但是他还是一个事务,Prepare阶段事务是不提交的,直到第二个阶段实物才会提交。所以他的事务更长,阻塞时间更差,性能更差。 所以,你也就能理解,为啥2PC是一个强一致性的了,因为他是一个事务,是严格遵循ACID的。而TCC是最终一致性,通过全局锁和重试机制保证最终一致。 所以,接着你就能理解,为啥2PC的性能很差,而TCC的性能还可以了。 所以,2PC适用于对事务一致性要求较高的场景,例如银行转账等,需要保证数据一致性和完整性。而TCC适用于对事务一致性要求不那么高的场景,例如电商库存扣减等,需要保证数据最终一致性即可。 维度 XA 2PC TCC 实现层 数据库资源层 应用层代理 事务机制 一个事务 多个事务 性能 低(阻塞时间长) 高(异步提交) 隔离性 高(数据库隔离级别) 弱(需全局锁辅助) 数据库要求 需支持XA协议 无特殊要求 回滚方式 数据库原生回滚 反向SQL补偿 适用场景 强一致、低并发 高并发、最终一致 TCC是强一致性还是最终一致性? ✅TCC是强一致性还是最终一致性? ...

March 22, 2026 · 1 min · santu

留言给博主