AT模式是Seata框架中的一种分布式事务解决方案,它利用两阶段提交(2PC)的概念,通过日志记录(在undo_log中)来实现在分布式系统中数据的一致性。AT模式可以解决分布式事务中的数据不一致问题,适合于RPC和微服务架构。
工作原理
AT模式通过以下两个阶段来保证分布式事务的一致性:
-
一阶段(Prepare阶段):业务数据和回滚日志(undo_log)记录
- 在业务操作的同时,记录业务操作前后的数据状态,生成回滚日志并保存在undo_log表中。
-
二阶段(Commit/Rollback阶段):事务提交或回滚
- 如果一阶段成功,二阶段将提交所有局部事务,并且异步清除undo_log。
- 如果一阶段中的任何操作失败,二阶段将根据undo_log中的信息回滚已执行的局部事务。
核心组件
- TC (Transaction Coordinator):事务协调器,维护全局事务状态,协调事务的提交或回滚。
- TM (Transaction Manager):事务管理器,定义全局事务的范围,负责开启和结束事务。
- RM (Resource Manager):资源管理器,管理分支事务处理的资源。
示例代码
假设您的系统中有订单服务和库存服务,您希望在创建订单的同时扣减库存。使用Seata进行事务管理的代码如下:
首先,配置Seata代理数据源:
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(properties.getUrl());
dataSource.setUsername(properties.getUsername());
dataSource.setPassword(properties.getPassword());
// 使用Seata对数据源进行包装
return new DataSourceProxy(dataSource);
}
}
然后,定义全局事务的业务逻辑:
@Service
public class BusinessService {
@Autowired
private OrderService orderService;
@Autowired
private InventoryService inventoryService;
@Transactional // 本地事务注解
@GlobalTransactional(timeoutMills = 300000, name = "fsp-create-order") // Seata全局事务注解
public void purchase(String userId, String commodityCode, int orderCount) {
// 1. 创建订单
orderService.createOrder(userId, commodityCode, orderCount);
// 2. 扣减库存
inventoryService.deduct(commodityCode, orderCount);
}
}
业务服务中,订单服务和库存服务的实现可能如下:
public class OrderService {
// 注入数据源或使用JdbcTemplate等
public void createOrder(String userId, String commodityCode, int orderCount) {
// 实现创建订单的逻辑
// 此处会有数据库操作,例如插入订单记录
}
}
public class InventoryService {
// 注入数据源或使用JdbcTemplate等
public void deduct(String commodityCode, int orderCount) {
// 实现扣减库存的逻辑
// 此处会有数据库操作,例如更新库存数量
}
}
细节分析
在使用AT模式时,需要注意以下关键点:
- undo_log表:确保数据库中有undo_log表,用于记录数据变更日志。
- 隔离级别:AT模式需要合适的隔离级别来避免脏读、幻读等问题。
- 幂等性:为了防止重复执行,需要确保业务逻辑的幂等性。
- 超时控制:设置合适的超时时间是重要的,防止事务挂起过久影响系统性能。
- 资源锁:Seata会锁定事务涉及的资源,需关注锁的粒度和持有时间。
- 服务降级:在Seata服务不可用时,应有降级策略保证业务可继续执行。
注意
实际部署Seata和AT模式,需要详细阅读Seata官方文档,并根据具体环境进行配置。以上代码演示是一个简化的例子,实际应用可能涉及更复杂的配置和错误处理策略。