本地事务的基本概念
- 
本地事物,通常想到的,如 ACID特性,通常在单个数据库中使用,由数据库本身来管理事务的提交和回滚。- 数据库事务的几个特性:原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation) 和持久性(Durabilily),简称就是 ACID。
- 原子性: 一系列的操作整体不可拆分,要么同时成功,要么同时失败
- 一致性: 数据在事务的前后,业务整体一致。
- 隔离性: 事务之间互相隔离。
- 持久性: 一旦事务成功,数据一定会落盘在数据库。
 
- 
分布式事务则涉及多个服务或数据库 ,需要 跨网络协调,保证不同节点之间数据的一致性。
本地事物在分布式下的问题
- 远程服务假失败 :远程服务成功,由于网络故障没有返回。如锁库存假失败,由于网络原因连接超时,但是锁库存已经操作成功。此时,会导致订单数据回滚而库存数据没有回滚(即库存扣减)。
- SpringBoot事物的坑 (事物失效问题)
为什么有分布式事物
- 因为微服务架构中,各个服务之间互相调用难免会出现一些问题(尤其网络问题),那么如果没有实现分布式事务,就会出现数据一致性问题。
1. 定义范围与数据源
- 
本地事务(Local Transaction) 
 范围 :在单个数据库或单个资源管理器内完成。
 示例 :银行扣款操作(仅操作自己的账户数据库 )。
 特点 :通过数据库的ACID特性(原子性、一致性、隔离性、持久性 )保证数据一致性。通过@Transactional注解管理单个数据库的ACID特性
- 
分布式事务(Distributed Transaction) 
 范围 :跨多个数据库、服务或资源管理器(如多个微服务、不同系统 )。
 示例 :跨行转账(操作A银行的账户扣款,同时操作B银行的账户加款)。
 特点 :需协调多个独立资源,解决网络延迟、节点故障等问题。例如微服务架构中订单服务和库存服务需协同完成事务
2、实现机制与特性
- 原子性保障
- 本地事务:数据库本身通过redo log和undo log实现原子性,若操作失败直接回滚本地数据。
- 分布式事务:依赖复杂协议(如两阶段提交2PC、补偿事务TCC)协调多个节点,例如Seata框架通过AT模式生成全局事物日志实现跨节点回滚。
- 一致性要求
- 本地事务:通过数据库锁机制(如行锁、表锁)和隔离级别(如可重复读)保障单库内一致性。
- 分布式事务:需解决网络延迟、节点故障等问题,可能需牺牲强一致性(CAP理论),采用最终一致性或Base理论(基本可用、软状态)。
- 协调机制
- 本地事物:无协调器,直接由数据库自身管理事物生命周期。
- 分布式事物:需引入事物协调器(如TM角色)管理全局事物状态,协调各参与者(RM角色)的提交或回滚。
3. 核心区别
| 对比维度 | 本地事务 | 分布式事务 | 
|---|---|---|
| 原子性实现 | 数据库日志(undo/redo) | 2PC、TCC、Saga等协议 | 
| 数据位置 | 同一数据库实例 | 跨多个数据库、服务或系统 | 
| 一致性模型 | 强一致性(ACID) | 最终一致性或妥协一致性(BASE理论) | 
| 实现复杂度 | 简单(数据库内置支持) | 复杂(需协调跨节点操作) | 
| 性能 | 高(无网络通信开销) | 低(网络延迟、协调成本高) | 
| 容错性 | 高(单点故障风险低) | 低(需处理网络分区、节点宕机等问题) | 
| 典型解决方案 | 数据库事务(如MySQL事务) | 两阶段提交(2PC)、TCC、Saga、消息事务 | 
| 应用场景 | 单服务库操作 | 跨服务、跨库的复杂操作 | 
4、性能与复杂度
- 性能开销
- 本地事务:无网络通讯和协调成本,执行效率高。
- 分布式事务:需多次跨节点通讯(如2PC的投票跟提交阶段),存在网络延迟跟资源锁定风险,性能显著下降。
- 实现复杂度
- 本地事务:实现简单,仅需数据库原生支持 (如SQL事物语句)。
- 分布式事物:需处理网络分区、节点故障、消息重试等复杂场景,例如通过MQ实现最终一致性或通过TCC预留资源。
5. 通俗比喻
- 
本地事务 : 
 单人单任务你一个人在家做饭,从 洗菜到炒菜全程自己控制,保证步骤连贯不出错。
- 
分布式事务 : 
 多人协作项目团队分工: A买食材,B切菜,C炒菜。需要协调每个人是否完成自己的任务,如果有人掉链子(如A没买到菜),整个项目可能失败。
6. 分布式cap定理和BASE理论
cap定理
- 指的是在一个分布式系统中,以下三种性质最多只能同时实现两点,不可能三者兼顾(CP/AP).
- 一致性(Consistency): 分布式系统中的所有数据备份,在同一时刻是否同样的值(等同于所有节点访问同一份最新的数据副本)
- 可用性(Availability): 集群一部分节点故障后,集群整体是否还能享用客户端读写请求。(对数据更新具备高可用性)
- 分区容错性(Partition tolerance): 大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是:区间通信可能失败。比如:一台服务器放在中国,另一台服务器放在美国,这就是两个区,他们之间可能无法通信。
 
- 一致性(Consistency): 
CP面临的问题
- 多数大型互联网应用场景,主机众多、部署分散,集群规模大。所以节点故障、网络故障是常态。要保证服务可用性达到 99.99999%(N 个 9) ,即保证 P 和 A,舍弃 C。
BASE理论
- 
对 CAP 理论的延伸 ,思想是 即使无法做到强一致性(CAP 的一致性就是强一致性),但可以适当的采取弱一致性即最终一致性。
- 
基本可用(Basically Available): - 
指 分布式系统在出现故障的时候,允许损失部分可用性(例如:响应时间、功能上的可用性)。需要注意的是,基本可用绝不等价于系统不可用。
- 
响应时间上的损失 :正常情况下 搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电或断网故障),查询结果的响应时间增加到了 1~2秒。
- 
功能上的损失:购物网站在购物高峰(如双十一时),为了保护系统的稳定性,部分消费者可能会被引导到一个降级页面。 
 
- 
- 
软状态(Soft State): - 软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据会有多个副本,允许不同副本同步的延时就是软状态的体现。mysql replication 的异步复制也是一种体现。
 
- 
最终一致性(Nventual Consistency): - 最终一致性是指系统中的所有数据副本经过一定时间后 ,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
 
- 最终一致性是指系统中的所有数据副本经过一定时间后 ,
7. 代码示例对比
本地事务(MySQL)
            
            
              java
              
              
            
          
          // 使用Spring的@Transactional注解管理单个数据库事务
@Transactional
public void transferLocal(int fromUserId, int toUserId, BigDecimal amount) {
    // 扣减转出账户余额
    accountDao.deduct(fromUserId, amount);
    // 增加转入账户余额(同一数据库)
    accountDao.add(toUserId, amount);
}分布式事务(TCC模式)
            
            
              java
              
              
            
          
          // 跨服务转账(TCC模式:Try-Confirm-Cancel)
public void transferDistributed(int fromUserId, int toUserId, BigDecimal amount) {
    // 1. Try阶段:预锁定资源
    boolean tryResult = bankATryService.deduct(fromUserId, amount); // 调用银行A的预扣款接口
    boolean tryResult2 = bankBTryService.add(toUserId, amount);     // 调用银行B的预收款接口
    if (tryResult && tryResult2) {
        // 2. Confirm阶段:提交事务
        bankAConfirmService.commit(fromUserId, amount); // 银行A实际扣款
        bankBConfirmService.commit(toUserId, amount);  // 银行B实际收款
    } else {
        // 3. Cancel阶段:回滚事务
        bankACancelService.rollback(fromUserId, amount);
        bankBCancelService.rollback(toUserId, amount);
    }
}8. 实际应用场景
- 
本地事务适用场景 : 
 单体应用内的订单创建(同一数据库操作)、库存扣减。
- 
分布式事务适用场景: - 跨行转账(不同银行系统)
- 电商下单(订单服务扣库存、支付服务收款)
- 微服务架构中跨服务数据更新(如用户注册后同步初始化多个子系统数据)
 
- 跨行转账(
9. 常见分布式事务解决方案
| 方案 | 原理 | 适用场景 | 
|---|---|---|
| 两阶段提交(2PC) | 协调者统一指挥参与者提交或回滚 | 数据库跨库事务(如分库分表) | 
| TCC模式 | Try预占资源 → Confirm提交 → Cancel回滚 | 高一致性要求的金融交易 | 
| Saga模式 | 长事务拆分为多个子事务,失败时反向补偿 | 跨服务业务流程(如订单+物流) | 
| 消息事务 | 基于消息队列的最终一致性(如RocketMQ) | 异步通知场景(如支付成功回调) | 
总结
- 本地事务 :简单高效,但仅限单一数据库。
- 分布式事务 :复杂但能解决跨系统协作问题,需权衡一致性与性能。
- 选择原则 :
- 优先避免分布式事务(如设计单一职责服务);
- 若无法避免,根据场景选择最终一致性或强一致性方案。