一、為什么需要Seata?
在微服務架構中,跨服務的事務管理成為核心痛點:
- 傳統事務失效:服務拆分導致無法使用本地事務
- 數據不一致風險:網絡抖動、服務宕機等情況導致數據錯亂
- 復雜場景處理難:涉及多個數據庫、消息隊列等異構存儲
Seata(Simple Extensible Autonomous Transaction Architecture) 是阿里開源的分布式事務解決方案,提供 AT模式、TCC模式、Saga模式 三種事務模型,支持高并發場景下的數據一致性。
二、核心概念與架構原理
2.1 核心角色
角色 | 說明 |
---|---|
TC (Transaction Coordinator) | 事務協調器,維護全局事務狀態(需獨立部署) |
TM (Transaction Manager) | 事務管理器,定義事務邊界(@GlobalTransactional注解) |
RM (Resource Manager) | 資源管理器,管理分支事務(連接數據庫等資源) |
2.2 AT模式核心原理
執行流程:
數據回滾機制:
- 階段一:執行業務SQL,保存前置鏡像(before image)和后置鏡像(after image)
- 階段二:
- 提交:異步刪除快照數據
- 回滾:用前置鏡像還原數據
三、環境搭建與配置(Spring Cloud Alibaba版)
3.1 組件版本
組件 | 版本 |
---|---|
Spring Boot | 2.6.11 |
Spring Cloud | 2021.0.4 |
Spring Cloud Alibaba | 2021.0.4.0 |
Seata Server | 1.7.0 |
3.2 Seata Server部署
# 下載并解壓
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
四、SpringBoot整合AT模式實戰
4.1 訂單服務配置
pom.xml:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
application.yml:
spring:cloud:alibaba:seata:tx-service-group: my_tx_group # 事務組名稱seata:registry:type: nacosnacos:server-addr: localhost:8848service:vgroup-mapping:my_tx_group: default # 對應TC集群
4.2 業務代碼示例
訂單服務(扣減庫存):
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate StorageFeignClient storageFeignClient;@GlobalTransactional // 開啟全局事務@Overridepublic 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模式實戰(適合高并發場景)
5.1 TCC核心概念
- Try:預留資源(如凍結庫存)
- Confirm:確認操作(真正扣減)
- Cancel:回滾操作(釋放資源)
5.2 庫存服務實現
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;
}
六、常見問題解決方案
6.1 TC服務無法注冊到Nacos
- 檢查Nacos服務是否正常啟動
- 確認registry.conf配置的namespace與Nacos一致
- 查看seata-server啟動日志是否有連接錯誤
6.2 全局事務不生效
- 確認@GlobalTransactional注解添加正確
- 檢查spring-cloud-alibaba-seata依賴版本
- 查看TM和RM是否使用相同的事務組配置
6.3 臟數據回滾失敗
- 檢查undo_log表是否自動創建
- 確認數據庫用戶有權限操作undo_log表
- 驗證AT模式下的SQL是否符合要求(必須有主鍵)
七、生產環境最佳實踐
-
TC服務高可用:
- 部署至少3個TC節點
- 使用Nacos集群做服務發現
-
數據持久化配置:
# conf/file.conf
store {mode = "db"db {datasource = "druid"dbType = "mysql"url = "jdbc:mysql://127.0.0.1:3306/seata"user = "root"password = "123456"}
}
- 監控告警:
- 集成Prometheus監控事務成功率
- 配置事務超時時間(默認60秒)
八、源碼解析(理解核心機制)
關鍵類說明:
類名 | 作用 |
---|---|
DefaultCoordinator | 事務協調核心邏輯 |
GlobalTransactionScanner | 掃描@GlobalTransactional注解 |
AsyncWorker | 異步處理分支提交/回滾 |
UndoLogManager | 管理數據快照 |
事務提交源碼片段:
public void commit() {// 異步執行提交AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {@Overridepublic void onSuccess(Boolean result) {// 刪除undo logundoLogManager.deleteUndoLog(xid, branchId);}};asyncWorker.branchCommit(branchType, xid, branchId, callback);
}