在微服務架構中,隨著系統模塊的拆分,單體應用中的本地事務已經無法滿足跨服務的數據一致性需求。此時,我們就需要引入分布式事務解決方案,比如 Seata。在使用 Seata 的過程中,很多人會遇到一個常見的疑問:
💬“我在調用方加了 @GlobalTransactional,服務提供方還需要加 @Transactional 嗎?”
答案是:必須要加!
這篇文章我們就深入講清楚:為什么服務提供方還需要加 @Transactional,以及兩者如何協作實現真正可靠的分布式事務。
🧩 一、事務的兩種類型
在討論這個問題之前,我們先要明確兩個事務注解的含義。
? 1. @GlobalTransactional
(Seata 分布式事務)
-
加在調用方法上,表示開啟一個全局事務。
-
屬于 Seata 的 AT 模式 事務注解,由 Seata 的 Transaction Coordinator (TC) 負責協調。
-
它會自動傳播全局事務上下文給遠程調用的服務。
? 2. @Transactional
(Spring 本地事務)
-
加在某個服務的方法上,表示方法內部的數據庫操作需要 在同一個本地事務中進行。
-
只有方法內部的操作在同一個本地事務中,Seata 才能在全局事務失敗時,正確地讓這些操作回滾。
📌 二、真實業務場景還原
我們以一個真實的訂單系統為例:
👇 業務流程:
-
用戶在訂單服務(A)中下單。
-
系統同時調用庫存服務(B)扣減庫存。
-
庫存服務還會記錄一條扣減日志到另一個表。
? 錯誤示范(服務B沒加 @Transactional
):
// A服務
@GlobalTransactional
public void createOrder() {orderMapper.insert(order);inventoryFeign.decreaseStock(); // 遠程調用 B 服務
}
// B服務
public void decreaseStock() {stockMapper.decrease(); // 成功logMapper.insertLog(); // 失敗,拋異常
}
這時候會發生什么?
-
A服務使用
@GlobalTransactional
,Seata 啟動了全局事務。 -
B服務沒有使用
@Transactional
,所以兩個表的操作并不在同一個本地事務中。 -
如果
logMapper.insertLog()
拋出異常,雖然 Seata 會通知回滾,但由于stockMapper.decrease()
已經提交,數據就不一致了!
? 正確示范(服務B加上 @Transactional
):
// B服務
@Transactional
public void decreaseStock() {stockMapper.decrease(); // 與下方操作屬于同一個本地事務logMapper.insertLog();
}
現在當 logMapper.insertLog()
拋出異常時:
-
Spring 會將整個 decreaseStock 方法回滾。
-
Seata 能檢測到異常,通知所有參與者事務回滾。
-
整個流程變成原子性的。
🔍 三、Seata 的本質:全局事務 + 本地事務協同
Seata 做的不是“接管”你的數據庫事務,而是:
在每個服務節點中使用代理數據源(DataSourceProxy),通過攔截本地事務的提交/回滾操作,來實現 全局的一致性控制。
因此:
-
@GlobalTransactional
控制“何時開始、是否提交全局事務” -
@Transactional
保證“本地數據庫操作的一致性和可回滾性”
你不加 @Transactional
,Seata 就沒法讓你的數據庫事務回滾,因為根本沒事務!
🛠 四、項目接入建議
如果你要使用 Seata 進行分布式事務控制,務必注意以下幾點:
配置項 | 說明 |
---|---|
? @GlobalTransactional | 放在業務流程發起方(一般是 Controller 或 Service) |
? @Transactional | 放在服務提供方處理數據庫操作的 Service 方法上 |
? 使用 Seata 的 DataSourceProxy | 所有數據源都要通過 Seata 的代理包裝 |
? 注冊到 Seata Server | 服務注冊中心需正確配置 Seata 服務 |
📚 五、總結
@GlobalTransactional 是分布式事務的起點,@Transactional 是本地事務的保障,二者缺一不可。
在微服務的世界里,要實現數據一致性,必須讓每個參與者都對自己的事務負責。Seata 會協調所有本地事務的提交和回滾,但它不會、也無法替你加上事務控制。
如果你覺得這篇文章對你有幫助,歡迎點贊、評論、收藏 ?
有任何問題也歡迎私信或留言交流!
📌 附推薦閱讀:
-
Seata 官方文檔
-
Spring Transactional 源碼解析
-
[分布式事務解決方案對比(Seata、TCC、消息最終一致性)]