微服务架构下,一个用户下单操作同时涉及订单、库存、账户三个服务,每个服务各自拥有数据库,本地事务无法跨服务生效。分布式事务用来解决这类跨服务数据一致性问题,Seata是目前使用率较高的中间件。本文对比其AT模式与TCC补偿模式,并给出可直接参考的后端实现代码。
Seata核心组件与部署
Seata由三部分组成:TC事务协调器、TM事务管理器、RM资源管理器。TM向TC申请全局事务,RM管理本地事务分支。
docker run -d --name seata-server \
-p 8091:8091 \
-e SEATA_IP=192.168.1.10 \
seataio/seata-server:2.0.0
业务服务引入seata-spring-boot-starter,配置事务分组与TC地址后即可接入。
# application.yml
seata:
enabled: true
application-id: order-service
tx-service-group: my_tx_group
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
AT模式实现与原理
AT模式对业务侵入最低,数据源代理自动记录分支事务的undo log,全局回滚时反向补偿。核心是全局事务范围加@GlobalTransactional注解。
@Service
public class OrderService {
@GlobalTransactional(timeoutMills = 360000)
public void createOrder(OrderDTO dto) {
orderMapper.insert(buildOrder(dto)); // 本地事务1
stockClient.deductStock(dto); // 远程事务2
accountClient.debit(dto.getAmount()); // 远程事务3
}
}
AT模式要求业务表存在并维护UNDO_LOG表,且所有参与方都经过Seata数据源代理。适用普通业务场景,性能上会多一次undo日志写入。
TCC补偿机制实现
TCC把事务拆成Try、Confirm、Cancel三个阶段,适合对一致性要求高、不允许脏读的金融链路。参与者需要自己编写补偿逻辑。
@LocalTCC
public interface AccountTCCService {
@TwoPhaseBusinessAction(
name = "debitAccount",
commitMethod = "commit",
rollbackMethod = "cancel"
)
boolean tryDebit(@BusinessActionContextParameter(paramName = "userId") Long userId,
@BusinessActionContextParameter(paramName = "amount") BigDecimal amount);
boolean commit(BusinessActionContext ctx);
boolean cancel(BusinessActionContext ctx);
}
@Service
public class AccountTCCServiceImpl implements AccountTCCService {
@Override
public boolean tryDebit(Long userId, BigDecimal amount) {
// 冻结资金,写入冻结表
return freezeService.freeze(userId, amount) > 0;
}
@Override
public boolean commit(BusinessActionContext ctx) {
// 冻结转扣款,需幂等
return accountDao.confirmDebit(ctx.getActionContext("userId"),
(BigDecimal) ctx.getActionContext("amount"));
}
@Override
public boolean cancel(BusinessActionContext ctx) {
// 解冻资金,需幂等
return freezeService.unfreeze(ctx.getActionContext("userId"),
(BigDecimal) ctx.getActionContext("amount"));
}
}
Confirm和Cancel必须幂等,Seata默认重试3次,接口设计上要保证重复调用结果一致。
AT与TCC模式选型对比
| 维度 | AT模式 | TCC模式 |
|---|---|---|
| 侵入性 | 低,无业务代码改造 | 高,需实现补偿接口 |
| 一致性 | 最终一致,即时性一般 | 最终一致,二阶段显式可控 |
| 性能 | 中等,有undo日志开销 | 较高,无锁表快照 |
| 适用场景 | 普通业务跨库操作 | 金融、库存等强一致链路 |
业务上优先AT降低开发成本,链路要求严格即时回滚的环节切换TCC。无论哪种模式,都要把幂等、超时、重试做到位,分布式事务才不会成为故障放大器。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/fen-bu-shi-shi-wu-hou-duan-kai-fa-shi-zhan-seataat-mo-shi/