在分布式数据库和微服务架构中,跨节点的SQL操作需要保证事务的ACID特性,XA、2PC、TCC、SAGA是四种主流的分布式事务实现模式,它们各自有不同的设计思路和适用边界。

四种模式的核心原理
2PC(两阶段提交)
2PC是最经典的分布式事务协议,分为准备阶段和提交阶段。协调者先向所有参与者发送准备请求,参与者执行SQL操作但不提交,返回准备结果;协调者收到所有参与者的成功响应后,再发送提交请求,参与者完成提交,否则发送回滚请求。
-- 2PC协调者伪代码示例 -- 准备阶段 PREPARE TRANSACTION 'tx_123'; -- 所有参与者返回成功后执行提交 COMMIT PREPARED 'tx_123'; -- 有参与者失败则执行回滚 ROLLBACK PREPARED 'tx_123';
XA
XA是X/Open组织定义的分布式事务规范,2PC是XA规范的核心实现逻辑。XA定义了资源管理器、事务管理器、应用程序的交互接口,支持跨多个异构数据库(如MySQL、PostgreSQL、Oracle)的事务协调,是数据库层面原生支持的分布式事务方案。
TCC(Try-Confirm-Cancel)
TCC是业务层面的分布式事务模式,将每个事务操作拆分为三个接口:Try阶段尝试预留资源,Confirm阶段确认执行操作,Cancel阶段取消预留资源。所有参与者的Try都成功后执行Confirm,任意一个失败则执行Cancel。
// TCC接口示例
public interface OrderTccService {
// 尝试预留库存、创建订单预记录
boolean tryCreateOrder(Order order);
// 确认订单生效
boolean confirmCreateOrder(Order order);
// 取消订单,释放预留资源
boolean cancelCreateOrder(Order order);
}
SAGA
SAGA模式将长事务拆分为多个本地短事务,每个本地事务都有对应的补偿事务。事务按顺序执行,如果某个本地事务失败,就按逆序执行前面所有事务的补偿操作,保证最终一致性。
// SAGA事务执行示例
public void createOrderSaga(Order order) {
// 步骤1:创建订单本地事务
orderService.createOrder(order);
try {
// 步骤2:扣减库存本地事务
inventoryService.deductStock(order.getProductId(), order.getCount());
} catch (Exception e) {
// 步骤2失败,执行步骤1的补偿
orderService.cancelOrder(order.getId());
throw e;
}
}
适用场景对比
| 模式 | 适用场景 |
|---|---|
| 2PC/XA | 参与节点少、事务执行时间短、对强一致性要求高的场景,比如单体应用拆分初期的跨库操作、金融核心转账类短事务 |
| TCC | 业务模型清晰、可以拆分出资源预留逻辑的场景,比如电商下单的库存预留、优惠券锁定,对性能要求较高且允许短期中间状态 |
| SAGA | 长事务场景,比如跨多个微服务的订单履约流程、涉及第三方系统调用的业务流程,对一致性要求为最终一致即可 |
代价对比
- 性能代价:2PC/XA需要阻塞所有参与者直到事务完成,性能损耗最高;TCC需要多次接口调用,性能损耗次之;SAGA是异步执行补偿,性能损耗最低。
- 开发代价:2PC/XA依赖数据库原生支持,开发成本最低;TCC需要为每个业务编写三个接口,开发成本最高;SAGA需要编写每个事务的补偿逻辑,开发成本中等。
- 一致性代价:2PC/XA支持强一致性,但是存在协调者单点故障风险;TCC和SAGA只支持最终一致性,可能出现短期数据不一致。
- 资源占用代价:2PC/XA会长时间持有数据库锁,资源占用高;TCC的Try阶段会预留资源,占用资源时间中等;SAGA的本地事务执行完就释放资源,占用最低。
选择建议
如果业务是短事务、参与节点少且需要强一致性,优先选择2PC/XA;如果是电商类业务,资源可以拆分预留,选择TCC;如果是长流程业务,涉及多个微服务调用,选择SAGA。同时需要结合团队的技术储备,TCC和SAGA需要更多的业务层开发,对团队的设计能力要求更高。