1. 项目概述:轻量级分布式事务补偿方案设计
在微服务架构中,分布式事务处理一直是个棘手的问题。传统方案如2PC、TCC往往需要引入额外中间件,增加了系统复杂度。最近我在一个电商订单项目中,尝试用SpringBoot+本地事务表+定时扫描的方案,实现了零中间件的分布式事务补偿机制。
这个方案的核心思想很简单:利用数据库本地事务保证操作记录和业务数据的原子性,通过定时任务扫描待补偿记录表进行后续处理。相比引入Seata等框架,这种方案的优势在于:
- 无额外组件依赖,纯数据库驱动
- 对现有代码侵入性小
- 适合中小规模分布式系统
- 实现成本低,运维简单
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心架构解析
2.1 本地事务表设计
补偿机制的核心是事务记录表,我的设计如下:
sql复制CREATE TABLE transaction_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
biz_id VARCHAR(64) NOT NULL COMMENT '业务ID',
biz_type VARCHAR(32) NOT NULL COMMENT '业务类型',
status TINYINT NOT NULL DEFAULT 0 COMMENT '0-待处理 1-处理中 2-成功 3-失败',
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
next_retry_time DATETIME COMMENT '下次重试时间',
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_biz (biz_type, biz_id)
) ENGINE=InnoDB;
关键设计点:
- 业务ID+业务类型唯一索引,防止重复记录
- 状态机设计,支持补偿流程控制
- 指数退避重试机制,通过next_retry_time实现
2.2 事务处理流程
典型的事务处理分为三个阶段:
- 主事务阶段:
java复制@Transactional
public void createOrder(OrderDTO order) {
// 1. 保存订单主数据
orderMapper.insert(order);
// 2. 扣减库存(远程调用)
boolean success = inventoryService.reduceStock(order.getProductId(), order.getCount());
// 3. 记录事务日志
if(success) {
transactionLogMapper.insert(new TransactionLog(
order.getOrderNo(),
"ORDER_CREATE",
TransactionStatus.PENDING
));
}
}
- 补偿任务阶段:
java复制@Scheduled(fixe
