TCC中,Confirm或者Cancel失败了怎么办?

典型回答 ✅什么是TCC,和2PC有什么区别? 关于TCC请看上面的链接。关于TCC,很多人会比较关心他在执行过程中的失败问题。 Confirm失败怎么办? 在TCC模式中,如果Confirm阶段失败,这通常意味着在尝试提交事务的过程中遇到了问题。处理这种情况需要根据特定的失败场景和系统设计来确定最合适的策略。以下是几种常见的处理方法: 1. 重试(用的最多) 一种常见的策略是重试Confirm操作。这通常适用于由于临时问题(如网络延迟、服务短暂不可用等)导致的失败。在重试之前,可以设定一个延迟或等待一段时间,然后再次尝试Confirm操作。通常,会设置重试次数的上限,以避免无限重试。 这个方案用的是最多的,之所以可以这么做,主要是因为在Try的过程中已经锁定了资源,那么在Confirm的时候,大概率是可以成功,而如果Confirm失败就执行Cancel,就会导致可能只是因为网络原因导致的时候就使得整个事务都Cancel了,而且这时候如果Cancel再失败怎么办呢?整个方案就会变得更加复杂了。 2. 执行Cancel操作 如果重试Confirm操作依然失败,或者系统确定Confirm无法成功,下一步是执行Cancel操作。Cancel阶段的目的是撤销在Try阶段预留的所有资源,确保系统回到事务开始前的状态。这是一种典型的回滚操作,用于处理事务失败的情况。 3. 日志记录和异常监控 在Confirm失败的情况下,重要的是记录详细的错误日志和监控异常。这可以帮助系统管理员或开发人员分析为什么Confirm操作失败,并采取相应的改进措施。此外,日志可以帮助在事后定位问题的根源。 4. 人工干预 在某些复杂或重要的事务中,如果自动化的重试和回滚失败,可能需要人工干预。这涉及到系统管理员或运维团队直接介入,手动处理故障和确保系统的一致性与稳定性。 Cancel失败怎么办? 在TCC中,cancel失败了怎么办呢? 一般有以下几种处理手段,和Confirm也差不多,无非就是报警、重试、人工干预。 记录日志&发送报警:将错误信息记录下来,方便后续分析和处理。并及时通知相关人员进行处理。 自动重试:在一定程度上,可以通过自动重试的方式尝试多次执行Cancel操作,直到成功为止。 人工干预:如果重试多次还是不成功, 可以报警,然后进行人工干预,可以尝试手动执行Cancel操作或者进行数据修复等。

March 22, 2026 · 1 min · santu

TCC是强一致性还是最终一致性?

典型回答 ✅什么是TCC,和2PC有什么区别? TCC 的过程是: Try阶段:尝试执行所有操作,并锁定所需资源以准备提交。 Confirm阶段:如果所有的Try操作成功,那么执行Confirm操作,最终提交事务。 Cancel阶段:如果任何Try操作失败,或者确认过程中遇到问题,执行Cancel操作来回滚所有的操作,释放锁定的资源。 通过他这个通过精心设计的流程,你就能看得出他的设计尽可能确保数据的一致性。 TCC 方案本身不提供强一致性,它提供的是最终一致性! 在分布式事务中,强一致性要求: 在任何时刻,从任何副本节点读取的数据,都是最新的、成功提交的数据。 事务的中间状态对用户是不可见的。 通过上面的TCC的流程我们可以知道,Try 阶段和 Confirm/Cancel 阶段之间是存在时间间隔的。在这个时间间隔内: 数据处于一种“中间状态”(如“资金已冻结但未扣款”)。 用户可能能看到这种中间状态(比如在银行APP里看到一部分钱被冻结了)。 所以,这种“中间状态可见”的特性,就违反了强一致性的定义。因此,从技术严格意义上讲,TCC 是最终一致性的。

March 22, 2026 · 1 min · santu

Seata的4种事务模式,各自适合的场景是什么?

✅Seata的实现原理是什么 AT模式 TCC模式 Saga模式 XA模式 首先AT模式,它的优点就是没有侵入性,你只需要按照Seata的要求引入@GlobalTransaction注解,就可以实现你的分布式事务了,他不需要做额外的操作,你只需要关注你的业务逻辑即可。 ✅Seata的AT模式的实现原理 但是他的局限性就是只能支持那种具有ACID属性的关系型数据库的操作,比如MySQL,因为他要基于日志进行回滚。如果你的项目中,需要把写数据库和写Redis放到同一个分布式事务中,AT模式就不支持了。 其次是TCC模式,这种模式可以支持多数据源的情况,不管你是Redis、MySQL还是ES,反正他就是要你自己实现Try、Confirm和Cancel,具体的逻辑你自己写,提交、回滚的代码你自己来实现就行了,所以他对代码有一定的侵入性。 ✅什么是TCC,和2PC有什么区别? 还有就是Saga这种模式,它适合长事务,什么是长事务呢?就是那种你有外部交互的场景,比如你要调微信支付,就可以用这种模式来管理这个分布式事务。 以上三种都是最终一致性,而XA模式这种就适合于你对一致性要求非常高的场景,只有他是一种强一致性模型。 ✅Seata的AT模式和XA有什么区别? Seata XA Seata AT Seata TCC Seata Saga 一致性 强一致 最终一致 最终一致 最终一致 隔离性 完全隔离 基于全局锁隔离 基于资源预留隔离 无隔离 代码侵入性 无 无 有,要编写TCC三个接口 有,要编写状态机及补偿代码 性能 差 高 非常高 非常高 适用场景 对一致性、隔离性要求较高的场景 基于关系型数据库的大多数分布式事务场景 对性能要求高的场景,有非关系型数据库要参与的事务 业务流程长且多。参与者包含外部接口或者遗留接口,无法做TCC模式的

March 22, 2026 · 1 min · santu

为什么不建议用数据库唯一性约束做幂等控制?

典型回答 在做幂等控制的时候,通常会选择基于数据库的唯一性约束来做,一般流程是这样的: 1、根据幂等字段查询是否有历史记录 2、如果有,则直接返回 3、如果没有,则执行数据库操作,并捕获数据库唯一性约束冲突异常 4、没有异常,返回成功 5、捕获到异常,反查一下数据,如果真的成功,则返回成功 大致的路基如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Boolean createUser(User user){ User existUser = userDao.getUserByTel(user.getTelephone()); if(existUser){ return true; } try{ return userDao.insert(user); }catch(DuplicateKeyException e){ User existUser = userDao.getUserByTel(user.getTelephone()); if(existUser){ return true; } } return false; } 首先我们说,这么做肯定是可以的,没啥大问题,一些小项目中,这么用也都是OK的。 ...

March 22, 2026 · 1 min · santu

Redis 分布式锁和zk分布式锁哪个对死锁友好_

典型回答 ✅Redis 的分布式锁和 Zookeeper 的分布式锁有啥区别? 这个问题其实是上面这个问题的衍生题,其实答案在上面这篇中已经有了,但是因为最近被问的比较多,所以就单独补充一下吧。 要说对死锁友好,Zookeeper 会比 Redis 更加友好一点。 什么叫死锁友好呢,就是可以减少锁的时长、提供自动释放等机制,就可以提前释放锁,就能降低死锁发生的概率,所谓的死锁友好。 而ZooKeeper在客户端崩溃时,链接会自动断开,那么就会自动删除崩溃客户端创建的锁节点,这样就相当于解锁了,那么就可以很大程度上来避免死锁。 而Redis锁虽然有超时释放的机制,但如果客户端在执行关键任务时突然崩溃,其他客户端需要等超时时间到了之后才能加锁成功。

March 22, 2026 · 1 min · santu

留言给博主