分布式事务

什么时候使用分布式事务

分布式事务不是怎么选的问题,首先就是能不用就不用 实在要用那就是 一致性等级划分问题
 
你必须先问:
  1. 是否必须强一致? 如果必须跨服务强一致,需要 CP 模型下的分布式事务机制,而不是单纯 ACID。 CP 模型下的分布式事务,本质是通过同步协调协议(如 2PC 或共识算法)在多个节点之间达成一致提交决议。
单库事务(ACID) 2PC(Two-Phase Commit,两阶段提交)TCC(Try-Confirm-Cancel,尝试确认取消)
  1. 是否允许最终一致? 如果是最终一致 那么就可以使用 outbox 就是AP模型
  2. 是否涉及资金? 涉及资金 → 必须保证强一致或可控一致性。常见选择:1:单库设计(优先)2:TCC 3:余额中心独立服务
  3. 是否允许补偿? 可以用 Outbox ,不允许补偿:必须同步强一致,必须阻塞失败回滚,补偿能力决定一致性策略
  4. QPS 多少?
100
可以 2PC
1000
TCC 或 本地事务
10000+
必须异步最终一致
高并发 + 强一致 = 性能灾难。
 

什么是qps

假设:
  • 1000 个用户 每分钟请求6次=6000 6000/60s=100qps QPS = 某段时间内的总请求数 / 时间(秒)
100 QPS × 单次事务耗时 = 并发事务数
 
第一步:估算单次事务耗时
假设:
  • 本地事务 30ms
  • 2PC 增加 2 次网络往返(RTT,Round Trip Time,网络往返时间)
  • 每次 RTT = 10ms
  • 总耗时 ≈ 30 + 2 × 10 = 50ms
第二步:计算并发事务数 公式: 并发数 ≈ QPS × 事务耗时(秒) 并发数 = 100 × 0.05 = 5个并发
mysql 的并发 可以调整到 1000+ 但是这只是并发请求 实际上的qps 是并发事务的响应时间
数据库并发通常有三层含义:
  1. 连接并发数(Connections,并发连接数) 一台服务器: 16 核 CPU 32GB 内存 典型 InnoDB 能承载: 2000+ 连接(但不都活跃)
  2. 活跃事务并发数(Active Transactions,活跃事务数) 并发能力 ≈ CPU 核心数 × 并行效率 一台服务器: 16 核 CPU 32GB 内存 典型 InnoDB 能承载: 200~500 活跃事务
  3. 真正执行 SQL 的并发线程数(Execution Concurrency,执行并发)
 
真正危险的不是高 QPS。 而是:长事务 × 热点数据
 
 
 
微服务并不一定需要分布式事务,关键取决于是否存在跨服务的强一致写操作。
在架构设计中,我会先做一致性等级划分:
  • 资金类场景采用 TCC 保证强一致
  • 单据流转类采用 Outbox 实现最终一致
  • 非核心数据采用异步处理
而不是默认所有微服务都使用分布式事务。

目前订单和销账是同一个库,同一个系统 所以是属于本地事务由数据库保证ACID

 
 
 
 
单机事务 → ACID
分布式系统 → CAP 约束
工程妥协 → BASE 思想
具体实现 → 2PC / TCC / Outbox / Saga
字母
含义
核心关注点
A Atomicity
原子性
要么全成要么全失败
C Consistency
一致性
不违反业务规则
I Isolation
隔离性
并发不干扰
D Durability
持久性
提交后不丢
 
 
维度
2PC
TCC
Outbox Pattern
Saga
一致性模型
强一致(CP)
强一致(可控)
最终一致(BASE)
最终一致(BASE)
本质机制
数据库层两阶段提交
业务层预留资源
本地事务+可靠消息
本地事务+补偿事务
是否阻塞
是
否(数据库层)
否
否
是否需要补偿
否
是(Cancel)
重试机制
必须有补偿
锁持有时间
长
短
本地事务时间
本地事务时间
对业务侵入
低
高
低
中等
性能
低
中
高
高
可扩展性
差
中
好
好
实现复杂度
中
高
低
中高
适合高QPS
不适合
可支持
非常适合
适合
资金核心
小规模可用
推荐
不推荐
不推荐
是否中心协调
有(Coordinator)
无中心锁
无
取决于编排方式
常见框架
XA / Atomikos
Seata TCC
自研+MQ
Axon / Seata Saga
一、2PC(Two-Phase Commit) ✅ 优点 理论简单 强一致 数据库原生支持(XA 协议(分布式事务协议)) ❌ 缺点 阻塞严重 协调者单点 扩展性差 长事务风险高 🎯 适用场景 低 QPS 系统 内部系统 节点数量少 对一致性要求极高 🚫 不适用 高并发 互联网核心交易 微服务大规模拆分 二、TCC(Try-Confirm-Cancel) ✅ 优点 强一致 不依赖数据库全局锁 支持高并发 扩展性优于 2PC ❌ 缺点 侵入业务逻辑 开发复杂 必须保证幂等(Idempotent,幂等性) Cancel 设计困难 🎯 适用场景 资金扣减 账户余额变更 库存冻结 支付系统 🚫 不适用 简单 CRUD 低价值系统 三、Outbox Pattern ✅ 优点 简单 性能好 无全局锁 不影响数据库并发能力 ❌ 缺点 最终一致 需要重试机制 需要消息幂等 🎯 适用场景 订单创建后发积分 用户注册后发通知 数据同步 统计系统 🚫 不适用 实时资金强一致 必须秒级对账一致的场景 四、Saga ✅ 优点 适合长事务 不阻塞 易扩展 ❌ 缺点 补偿逻辑复杂 数据可能短时间不一致 业务侵入明显 🎯 适用场景 电商完整下单流程 跨多个微服务 需要事务编排 🚫 不适用 实时账务系统 高精度金融核心
 

cap举例

CAP 定理

  • C(Consistency) 一致性
  • A(Availability)原子性
  • P(Partition tolerance)
四、为什么必须二选一? 假设场景: 两个节点: Node A Node B 账户余额 = 100 突然网络断开(分区发生) A 和 B 无法通信。 此时发生写请求: 用户在 Node A 扣减 30。 A 变成 70。 现在问题来了: 用户去 Node B 查询余额。 你有两个选择: 选择 1:保证强一致 Node B 不能确认 A 是否已更新。 为了保证一致: 👉 B 必须拒绝请求或等待网络恢复。 结果: 查询失败 服务不可用 你保住了一致性 但牺牲了可用性 这是 CP。 选择 2:保证可用性 Node B 直接返回当前值 100。 结果: 用户看到旧数据 数据不一致 但系统可用。 这是 AP。 五、这就是为什么必须二选一 因为: 分区发生时,节点之间无法同步。 你无法同时做到: 所有节点数据一致 所有节点都响应请求 这是一个数学证明结论。 不是工程选择问题。
 

mvcc 是要是适用了innodb存储引擎 那么会自动实现

什么是乐观锁和状态机

拿销账举例 销账更新金额的时候 读不进行租塞,写的时候进行判断 所以可以在表中增加版本号,因为销账有流程为了保证更安全还可以加上状态机 就是待处理只可以变成处理中
ef虽然实现了乐观锁 只需要加上特性就好 但是性能有问题 因为1000条他就会生产1000个update语句
 
 
 

XA 事务不是 .NET 特有的事务机制,它是数据库层面支持的分布式事务协议。

在 .NET 中如果使用 TransactionScope 并跨多个数据库连接,可能会触发 MSDTC,而 MSDTC 底层可能会使用数据库的 XA 实现两阶段提交。
 

一、三者本质定位

方案
本质类型
控制层级
2PC(XA)
数据库层分布式事务
资源管理器
TCC
业务层两阶段提交
应用层
Outbox
本地事务 + 可靠消息
架构层
一句话总结:
  • 2PC:让数据库帮你做分布式事务
  • TCC:让业务帮你做分布式事务
  • Outbox:避免分布式事务

二、分别解决了什么问题?


一、2PC(Two-Phase Commit)

解决的问题

多个数据库之间如何保证原子提交?
典型场景:
  • 跨库更新
  • 跨数据源事务

工作机制

阶段 1:Prepare
协调者询问所有参与者是否可以提交
阶段 2:Commit / Rollback

优点

  • 强一致
  • 实现简单(框架支持)
  • 对业务无侵入

缺点

  • 同步阻塞
  • 锁时间长
  • 协调者单点
  • 性能差
  • 容易雪崩

适用场景

  • 银行核心账务
  • 并发不高
  • 强一致优先
  • 内网系统
互联网系统几乎不用。

二、TCC(Try-Confirm-Cancel)

解决的问题

在高并发环境下,如何保证强一致,同时避免数据库长锁?

工作机制

Try:预留资源 (冻结金额)
Confirm:正式提交(扣减金额)
Cancel:回滚补偿(解冻金额)
本质:业务层 2PC

优点

  • 强一致
  • 不依赖数据库锁
  • 并发能力高于 XA

缺点

  • 侵入性强
  • 需要三套接口
  • 要处理空回滚、悬挂问题
  • 必须幂等
  • 实现复杂

适用场景

  • 账户余额扣减
  • 冻结资金
  • 支付系统
  • 金融级强一致场景
财务系统“钱”的场景。

三、Outbox Pattern

解决的问题

本地事务成功,但消息发送失败导致数据不一致
核心:
本地事务写:
  • 业务数据
  • 消息记录
异步发送。

优点

  • 高性能
  • 无分布式锁
  • 架构简单
  • 互联网主流方案

缺点

  • 最终一致
  • 需要幂等
  • 需要补偿机制
  • Outbox 表膨胀问题

适用场景

  • 订单状态流转
  • 业务事件通知
  • 电商系统
  • 高并发系统
财务系统“单据流转”的场景。

三、架构级对比表

对比维度
2PC
TCC
Outbox
一致性
强一致
强一致
最终一致
锁资源
数据库锁
业务冻结
无锁
并发能力
低
中
高
侵入性
低
高
低
实现复杂度
低
高
中
是否阻塞
是
部分
否
是否适合互联网
不适合
部分场景
非常适合

四、从“解决问题的思路”角度理解

2PC 思路:

把多个数据库当成一个数据库

TCC 思路:

不依赖数据库锁,用业务状态控制一致性

Outbox 思路:

不做分布式事务,用可靠消息保证最终一致

五、财务系统里的正确分级设计

场景
推荐方案
账户余额扣减
TCC
销账单生成
Outbox
订单状态流转
Outbox
跨库强一致账务
2PC(极少)

六、面试高级回答模板

你可以这样回答:
2PC 是数据库层分布式事务方案,保证强一致,但性能较低,适用于并发不高的金融核心系统。
TCC 是业务层两阶段提交,通过冻结资源实现强一致,适合资金类场景,但侵入性较高。
Outbox 是通过本地事务写消息表,再异步发送消息实现最终一致,是互联网系统主流方案,适合高并发业务场景。
在实际架构中,应根据一致性等级分级设计,而不是一刀切。

七、真正架构师的思考方式

 
posted @ 2026-03-05 16:00  12不懂3  阅读(67)  评论(0)    收藏  举报
创作不易,请勿抄袭,欢迎转载!