在微服务架构中,跨服务的事务管理成为核心痛点:
Seata(Simple Extensible Autonomous Transaction Architecture) 是阿里开源的分布式事务解决方案,提供 AT模式、TCC模式、Saga模式 三种事务模型,支持高并发场景下的数据一致性。
角色 | 说明 |
---|---|
TC (Transaction Coordinator) | 事务协调器,维护全局事务状态(需独立部署) |
TM (Transaction Manager) | 事务管理器,定义事务边界(@GlobalTransactional注解) |
RM (Resource Manager) | 资源管理器,管理分支事务(连接数据库等资源) |
执行流程:
数据回滚机制:
组件 | 版本 |
---|---|
Spring Boot | 2.6.11 |
Spring Cloud | 2021.0.4 |
Spring Cloud Alibaba | 2021.0.4.0 |
Seata Server | 1.7.0 |
# 下载并解压
wget https://github.com/seata/seata/releases/download/v1.7.0/seata-server-1.7.0.zip
unzip seata-server-1.7.0.zip
# 修改配置文件 conf/registry.conf
registry {
type = "nacos"
nacos {
serverAddr = "localhost:8848"
namespace = ""
cluster = "default"
}
}
# 启动服务端
sh bin/seata-server.sh -p 8091 -h 127.0.0.1
pom.xml:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-seataartifactId>
dependency>
application.yml:
spring:
cloud:
alibaba:
seata:
tx-service-group: my_tx_group # 事务组名称
seata:
registry:
type: nacos
nacos:
server-addr: localhost:8848
service:
vgroup-mapping:
my_tx_group: default # 对应TC集群
订单服务(扣减库存):
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private StorageFeignClient storageFeignClient;
@GlobalTransactional // 开启全局事务
@Override
public void createOrder(OrderDTO orderDTO) {
// 1. 本地事务:创建订单
orderMapper.create(orderDTO);
// 2. 远程调用:扣减库存
storageFeignClient.deduct(orderDTO.getProductId(), orderDTO.getCount());
// 测试回滚
// int i = 1/0;
}
}
库存服务(Feign接口):
@FeignClient(name = "storage-service")
public interface StorageFeignClient {
@PostMapping("/storage/deduct")
void deduct(@RequestParam("productId") Long productId,
@RequestParam("count") Integer count);
}
TCC接口定义:
public interface StorageTccService {
@TwoPhaseBusinessAction(name = "deduct",
commitMethod = "confirm",
rollbackMethod = "cancel")
boolean tryDeduct(@BusinessActionContextParameter(paramName = "productId") Long productId,
@BusinessActionContextParameter(paramName = "count") Integer count);
boolean confirm(BusinessActionContext context);
boolean cancel(BusinessActionContext context);
}
Try阶段实现:
@Override
public boolean tryDeduct(Long productId, Integer count) {
// 冻结库存(非实际扣减)
storageMapper.freezeStock(productId, count);
return true;
}
Cancel阶段实现:
@Override
public boolean cancel(BusinessActionContext context) {
Long productId = Long.valueOf(context.getActionContext("productId").toString());
Integer count = Integer.valueOf(context.getActionContext("count").toString());
// 释放冻结库存
storageMapper.unfreezeStock(productId, count);
return true;
}
TC服务高可用:
数据持久化配置:
# conf/file.conf
store {
mode = "db"
db {
datasource = "druid"
dbType = "mysql"
url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "root"
password = "123456"
}
}
关键类说明:
类名 | 作用 |
---|---|
DefaultCoordinator | 事务协调核心逻辑 |
GlobalTransactionScanner | 扫描@GlobalTransactional注解 |
AsyncWorker | 异步处理分支提交/回滚 |
UndoLogManager | 管理数据快照 |
事务提交源码片段:
public void commit() {
// 异步执行提交
AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
@Override
public void onSuccess(Boolean result) {
// 删除undo log
undoLogManager.deleteUndoLog(xid, branchId);
}
};
asyncWorker.branchCommit(branchType, xid, branchId, callback);
}