Seata AT模式详解与实践
2025/9/17大约 4 分钟
Seata AT模式详解与实践
前置知识
在学习本教程之前,请确保您已经:
- 了解Seata的基本概念
- 掌握Spring Boot和Spring Cloud的基础知识
- 理解数据库事务和隔离级别
AT模式简介
AT(Automatic Transaction)模式是Seata提供的一种无侵入的分布式事务解决方案。它的特点是:
- 对业务无侵入:使用简单,开发成本低
- 自动补偿:框架自动生成反向SQL
- 性能较好:本地事务的性能损耗小
工作原理
AT模式的工作流程分为两个阶段:
一阶段:
- 拦截业务SQL
- 解析SQL语义
- 保存前镜像
- 执行业务SQL
- 保存后镜像
- 生成行锁
二阶段:
- 提交:释放行锁
- 回滚:根据前后镜像生成反向SQL并执行
实现原理
1. UNDO LOG
AT模式通过UNDO LOG实现事务回滚:
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2. 全局锁
AT模式使用全局锁来保证事务隔离性:
@Service
public class OrderServiceImpl implements OrderService {
@GlobalTransactional
public void createOrder(Order order) {
// Seata会自动获取全局锁
orderMapper.insert(order);
}
}
快速实践
1. 数据库准备
创建业务表和UNDO LOG表
-- 订单表
CREATE TABLE `order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` varchar(32) NOT NULL,
`product_id` varchar(32) NOT NULL,
`amount` int(11) NOT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 库存表
CREATE TABLE `stock` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`product_id` varchar(32) NOT NULL,
`count` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 实体类定义
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private Long id;
private String userId;
private String productId;
private Integer amount;
private Integer status;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Stock {
private Long id;
private String productId;
private Integer count;
}
3. 业务实现
@Service
@Slf4j
public class BusinessService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private StockMapper stockMapper;
@GlobalTransactional
public void createOrder(String userId, String productId, int amount) {
// 创建订单
Order order = new Order();
order.setUserId(userId);
order.setProductId(productId);
order.setAmount(amount);
order.setStatus(0);
orderMapper.insert(order);
// 扣减库存
Stock stock = stockMapper.selectByProductId(productId);
if (stock.getCount() < amount) {
throw new RuntimeException("库存不足");
}
stock.setCount(stock.getCount() - amount);
stockMapper.updateById(stock);
}
}
最佳实践
使用建议
注意事项
- 避免大事务:事务涉及的数据量要适中
- 并发处理:注意全局锁导致的死锁问题
- 异常处理:合理处理业务异常和系统异常
- 超时控制:设置合适的事务超时时间
优化建议
- 精简数据:只操作必要的数据
- 索引优化:确保SQL语句高效执行
- 批量处理:合理使用批量操作提升性能
性能优化
seata:
client:
rm:
# 异步提交缓存队列长度
async-commit-buffer-limit: 10000
# 一阶段结果上报TC重试次数
report-retry-count: 5
tm:
# 事务超时时间
default-global-transaction-timeout: 60000
# 事务回滚重试次数
rollback-retry-count: 5
常见问题
1. AT模式的脏写问题如何解决?
AT模式通过全局锁机制来避免脏写。当事务需要更新数据时,会先获取全局锁,避免其他事务同时更新相同的数据。
2. AT模式的性能瓶颈在哪里?
主要瓶颈:
- 全局锁的获取和释放
- UNDO LOG的记录和解析
- 网络通信开销
优化建议:
- 使用异步提交
- 合理设置事务边界
- 优化锁粒度
总结
本文详细介绍了Seata AT模式的实现原理和使用方法:
- ✅ 基本原理:两阶段提交、UNDO LOG机制
- ✅ 实现细节:自动补偿、全局锁、隔离级别
- ✅ 实践示例:完整的业务场景实现
- ✅ 最佳实践:性能优化和注意事项
- ✅ 常见问题:脏写问题和性能瓶颈
下一步学习
- 了解TCC模式的实现原理
- 学习Saga模式的应用场景
- 探索XA模式的使用方法