深入理解XA、AT、TCC、MQ四种事务模式的原理与应用
核心理念:基于X/Open XA规范的两阶段提交协议(2PC),确保分布式事务的ACID特性。在CAP理论中,XA模式选择了一致性(C)和分区容错性(P),牺牲了可用性(A)。
TC (Transaction Coordinator)
数据库A
数据库B
数据库C
// 1. 配置XA数据源 @Configuration public class XADataSourceConfig { @Bean @Primary public DataSource dataSource() { AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean(); dataSource.setUniqueResourceName("xa-datasource"); dataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource"); dataSource.setXaProperties(xaProperties()); return dataSource; } } // 2. 业务服务使用全局事务注解 @Service public class TransferService { @Autowired private AccountService accountService; @GlobalTransactional(rollbackFor = Exception.class) public void transferMoney(String fromAccount, String toAccount, BigDecimal amount) { try { // 第一阶段:所有操作都会执行但不提交 // 步骤1:扣减源账户余额 accountService.debit(fromAccount, amount); // 步骤2:增加目标账户余额 accountService.credit(toAccount, amount); // 步骤3:记录转账日志 logService.recordTransfer(fromAccount, toAccount, amount); // 如果所有步骤都成功,Seata会协调所有参与者提交事务 // 如果任何步骤失败,所有操作自动回滚 } catch (Exception e) { // 异常时,@GlobalTransactional会触发全局回滚 throw e; } } }
核心理念:基于undo_log的自动补偿机制,在保证性能的同时实现分布式事务。AT模式选择了可用性(A)和分区容错性(P),通过最终一致性来平衡。
管理全局事务
正常业务表
回滚日志表
行级锁机制
// 1. 创建undo_log表(Seata自动使用) CREATE TABLE undo_log ( id bigint(20) NOT NULL AUTO_INCREMENT, branch_id bigint(20) NOT NULL COMMENT '分支事务ID', xid varchar(100) NOT NULL COMMENT '全局事务ID', context varchar(128) NOT NULL COMMENT '事务上下文', rollback_info longblob NOT NULL COMMENT '回滚信息', log_status int(11) NOT NULL COMMENT '日志状态', log_created datetime NOT NULL COMMENT '创建时间', log_modified datetime NOT NULL COMMENT '修改时间', PRIMARY KEY (id), UNIQUE KEY ux_undo_log (xid,branch_id) ); // 2. 业务服务 - AT模式使用 @Service public class OrderService { @GlobalTransactional(rollbackFor = Exception.class) public void createOrder(Order order) { // 步骤1:创建订单 orderRepository.save(order); // 步骤2:扣减库存 stockService.reduceStock(order.getProductId(), order.getQuantity()); // 步骤3:扣减账户余额 accountService.deductBalance(order.getUserId(), order.getAmount()); } }
核心理念:通过Try、Confirm、Cancel三个阶段实现分布式事务,业务逻辑需要主动实现补偿机制。TCC是一种应用层的两阶段提交,给予业务更大的控制权。
预留资源
检查约束
确认执行
提交资源
取消执行
释放资源
// 1. TCC接口定义 @LocalTCC public interface AccountTccService { @TwoPhaseBusinessAction( name = "debit", commitMethod = "confirm", rollbackMethod = "cancel" ) boolean debit(@BusinessActionContextParameter(paramName = "userId") String userId, @BusinessActionContextParameter(paramName = "amount") BigDecimal amount); boolean confirm(BusinessActionContext context); boolean cancel(BusinessActionContext context); } // 2. TCC实现 - Try阶段冻结金额 @Override public boolean debit(String userId, BigDecimal amount) { // Try阶段:预留资源(冻结金额) Account account = accountRepository.findByUserId(userId); if (account.getBalance().compareTo(amount) < 0) { throw new RuntimeException("账户余额不足"); } // 冻结金额 FrozenAmount frozenAmount = new FrozenAmount(); frozenAmount.setUserId(userId); frozenAmount.setAmount(amount); frozenAmount.setStatus("FROZEN"); frozenAmountRepository.save(frozenAmount); return true; }
核心理念:基于消息队列的事务消息机制,通过异步消息确保分布式事务的最终一致性。这是性能最优的方案,但需要业务容忍一定的延迟。
发送事务消息
RocketMQ/Kafka
消费消息
消费消息
// 1. 发送事务消息 @Service public class OrderService { @Autowired private TransactionMQProducer producer; public void createOrder(Order order) { Message message = new Message( "ORDER_TOPIC", "CREATE_ORDER", order.getOrderId(), JSON.toJSONString(order).getBytes() ); TransactionSendResult result = producer.sendMessageInTransaction(message, order); } } // 2. 事务监听器 @Component public class OrderTransactionListener implements TransactionListener { @Override public LocalTransactionState executeLocalTransaction(Message msg, Object arg) { try { Order order = (Order) arg; orderRepository.save(order); return LocalTransactionState.COMMIT_MESSAGE; } catch (Exception e) { return LocalTransactionState.ROLLBACK_MESSAGE; } } @Override public LocalTransactionState checkLocalTransaction(MessageExt msg) { String orderId = msg.getKeys(); Order order = orderRepository.findByOrderId(orderId); return order != null ? LocalTransactionState.COMMIT_MESSAGE : LocalTransactionState.ROLLBACK_MESSAGE; } }
| 对比维度 | XA模式 | AT模式 | TCC模式 | MQ模式 |
|---|---|---|---|---|
| 一致性 | 强一致性 | 最终一致性 | 最终一致性 | 最终一致性 |
| 性能 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 开发复杂度 | 简单 | 简单 | 复杂 | 中等 |
| 业务侵入性 | 无 | 无 | 高 | 中等 |
| 适用场景 | 金融核心系统 | 一般业务系统 | 复杂业务场景 | 高并发异步场景 |
| 技术门槛 | 低 | 低 | 高 | 中等 |
| 资源锁定时间 | 长 | 短 | 可控 | 无锁定 |
| 支持的存储 | 支持XA的数据库 | 关系型数据库 | 任意存储 | 任意存储 |
选择 XA模式
适用于金融核心系统、支付系统等对数据一致性要求极高的场景
选择 AT模式
适用于大部分业务场景,是最推荐的默认选择
选择 TCC模式
适用于定制化要求高、跨系统复杂业务场景
选择 MQ模式
适用于高并发、允许异步处理的业务场景