關于Seata基本使用及二階提交流程
一,Seata 的基本使用
環(huán)境搭建:
- 下載 Seata:可以從 Seata 官網(wǎng) 或者 GitHub 上獲取最新版本。
- 啟動 Seata Server:下載 Seata 后,配置并啟動 Seata Server,Seata 提供了一個默認的 Nacos 配置中心,也可以使用其他配置中心。
引入依賴:
- 在微服務應用中,可以通過 Maven 或 Gradle 引入 Seata 的相關依賴。
<dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.6.1</version> <!-- 根據(jù)需要選擇最新版本 --> </dependency>
配置 Seata
- 在使用全局事務之前,需要確保 Seata Server 已經(jīng)啟動,并且應用程序的
application.yml
配置正確
seata: tx-service-group: my_test_tx_group # 事務分組 service: vgroup-mapping: my_test_tx_group: default enable-auto-data-source-proxy: true # 自動代理數(shù)據(jù)源 registry: type: nacos # 注冊中心類型 nacos: server-addr: 127.0.0.1:8848 # Nacos 地址 namespace: public group: SEATA_GROUP config: type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: public group: SEATA_GROUP
在全局事務中使用 @GlobalTransactional
- 全局事務的控制需要在方法上添加
@GlobalTransactional
,以確保該方法及其調(diào)用的所有子事務受 Seata 統(tǒng)一管理。
import io.seata.spring.annotation.GlobalTransactional; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; @Service public class OrderService { @Autowired private StockService stockService; @Autowired private PaymentService paymentService; @GlobalTransactional(name = "order-create", rollbackFor = Exception.class) public void createOrder(String userId, String productId, int amount) { // 扣減庫存 stockService.deductStock(productId, amount); // 處理支付 paymentService.processPayment(userId, amount); // 插入訂單記錄 System.out.println("訂單創(chuàng)建成功!"); } }
在分支事務中使用 @Transactional
- Seata 在全局事務中,所有數(shù)據(jù)庫操作會自動成為分支事務。
- 在
StockService
中:
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StockService { @Transactional public void deductStock(String productId, int amount) { // 執(zhí)行數(shù)據(jù)庫庫存扣減操作 System.out.println("庫存扣減成功!"); } }
雖然 StockService
仍然使用的是本地事務 @Transactional
,但因@GlobalTransactional
處于全局事務上下文中,Seata 會自動代理并管理它的事務
二,Seata 的工作原理
Seata 通過引入 全局事務管理 和 分支事務 來解決分布式系統(tǒng)中的事務一致性問題。
它使用類似于傳統(tǒng)數(shù)據(jù)庫事務中的 二階段提交(2PC,Two-Phase Commit) 協(xié)議來確保事務的原子性。
二階段提交(2PC)過程
Seata 采用二階段提交協(xié)議(2PC)來確保分布式事務的一致性。以下是二階段提交的詳細流程:
1. 第一階段:事務預備(Try階段)
- 全局事務開始:客戶端應用向 Seata Server 發(fā)起請求,Seata 會生成一個全局事務 ID(XID),并返回給客戶端應用。全局事務標識用于追蹤整個分布式事務。
// 啟動全局事務 GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate(); tx.begin();
- 分支事務注冊:每個參與者(微服務)啟動后,會向 Seata Server 注冊自己作為一個分支事務,Seata Server 會為每個分支事務分配一個唯一的事務分支 ID(Branch ID)。
- Try 階段:每個微服務會執(zhí)行 Try 操作,即準備執(zhí)行本地事務操作,但不提交數(shù)據(jù)。例如,更新某個數(shù)據(jù)庫中的記錄,但不提交。
- 執(zhí)行數(shù)據(jù)庫操作:每個參與的子事務都會執(zhí)行數(shù)據(jù)庫更新,但不會真正提交,而是進入
prepare
狀態(tài)(對于 AT 模式,這意味著生成 undo_log)。
2. 第二階段:提交(Commit)或回滾(Rollback)
提交(Commit):
- Seata Server 收到全局事務提交請求后,通知所有分支事務提交事務。
- 分支事務提交數(shù)據(jù)庫操作(刪除
undo_log
)。
回滾(Rollback):
- 如果 Seata Server 發(fā)現(xiàn)某個分支事務執(zhí)行失敗,則通知所有已提交的分支事務回滾,恢復
undo_log
記錄的數(shù)據(jù)。
三,Seata 的四種事務模式
1. AT 模式(自動事務模式)
AT(Auto Transaction)模式是 Seata 中最常用的分布式事務模式,適用于對數(shù)據(jù)庫執(zhí)行常規(guī)的 CRUD(增、刪、改、查)操作的場景,尤其是簡單的 SQL 操作。
特點:
- 自動化:AT 模式在數(shù)據(jù)庫的每個操作上都自動代理,開發(fā)者無需顯式地編寫事務的提交和回滾操作。Seata 會自動插入 undo 日志,在事務回滾時自動恢復數(shù)據(jù)庫的原始狀態(tài)。
- 無須業(yè)務代碼改動:AT 模式的關鍵優(yōu)勢是,開發(fā)者無需修改現(xiàn)有的業(yè)務代碼。通過 Seata 自動管理事務,開發(fā)者只需確保數(shù)據(jù)庫支持 undo 日志(例如 MySQL、Oracle 等)。
- 僅適用于數(shù)據(jù)庫操作:AT 模式適用于標準的數(shù)據(jù)庫操作,它依賴于數(shù)據(jù)庫的日志和 undo 日志機制。
工作原理:
- Try 階段:Seata 會攔截數(shù)據(jù)庫的更新操作,并記錄 undo 日志,但不立即提交。此時,數(shù)據(jù)庫的數(shù)據(jù)并未真正修改,而是保留了“回滾”的信息。
- Commit 階段:當全局事務提交時,Seata 會通過協(xié)調(diào)所有分支事務,最終確認提交所有的數(shù)據(jù)修改。
- Rollback 階段:如果全局事務失敗,則會通過回滾所有分支事務的操作,恢復數(shù)據(jù)。
適用場景:
- 適用于大多數(shù)微服務場景,尤其是直接依賴數(shù)據(jù)庫操作的業(yè)務邏輯,Seata 會自動進行事務控制。
2. TCC 模式(Try-Confirm-Cancel)
TCC(Try-Confirm-Cancel)模式是一種基于補償?shù)姆植际绞聞漳J剑m用于業(yè)務操作較為復雜、涉及多個服務的場景。與 AT 模式的自動提交和回滾不同,TCC 模式要求開發(fā)者顯式地實現(xiàn) Try、Confirm 和 Cancel 這三個階段。
特點:
- 精確控制:開發(fā)者需要編寫 Try、Confirm 和 Cancel 方法,能夠精確控制每個階段的事務操作。
- 高靈活性:TCC 模式適用于復雜的業(yè)務操作,尤其是那些需要進行資源鎖定、狀態(tài)更新、外部系統(tǒng)調(diào)用的場景。
- 手動補償:TCC 模式的關鍵是補償機制,若某個操作失敗,需要通過 Cancel 操作來撤銷之前的資源占用或狀態(tài)變更。
工作原理:
- Try 階段:執(zhí)行實際的業(yè)務操作,但不會提交(例如,鎖定資源、預扣資金)。此時,操作是冪等的,并且不改變系統(tǒng)狀態(tài)。
- Confirm 階段:如果 Try 階段成功,Confirm 階段會提交操作,確認業(yè)務操作完成(例如,實際扣款、最終更新庫存)。
- Cancel 階段:如果 Try 階段失敗或某個分支事務失敗,則執(zhí)行 Cancel 操作,撤銷之前的操作(例如,解鎖資源、退款)。
適用場景:
- 長時間執(zhí)行的業(yè)務:例如支付、庫存扣減等復雜的跨服務操作,需要實現(xiàn)顯式的補償機制。
- 必須確保操作的最終一致性:TCC 能夠處理在服務之間的協(xié)作,并確保每個服務能明確知道何時提交或回滾事務。
3. SAGA 模式
SAGA(長事務模式)是一個分布式事務處理模式,適用于跨多個微服務的長事務。與 TCC 模式不同,SAGA 模式通過將長事務拆分成多個小事務來保證一致性,每個小事務都會有一個補償事務(Compensating Transaction),用于回滾操作。
特點:
- 長事務拆分:將大事務拆分為一系列小事務,每個小事務都可以獨立提交或回滾。
- 補償機制:每個小事務都需要實現(xiàn)一個補償事務,當某個事務失敗時,通過補償事務來撤銷之前的操作。
- 可以異步執(zhí)行:每個子事務之間可以獨立執(zhí)行,并且可以異步執(zhí)行,不需要像 TCC 那樣鎖定資源。
工作原理:
- 子事務:將全局事務拆分為多個子事務,每個子事務執(zhí)行獨立的操作(例如,支付、庫存扣減等)。
- 補償操作:每個子事務都有相應的補償操作。如果某個子事務失敗,執(zhí)行補償操作撤銷之前的操作。
- 全局事務結束:當所有子事務都執(zhí)行成功時,結束整個 SAGA 事務;如果某個子事務失敗,則根據(jù)補償規(guī)則進行回滾。
適用場景:
- 長時間的、跨多個服務的事務:例如訂單的創(chuàng)建、支付、發(fā)貨等操作。
- 能夠容忍部分失敗的場景:SAGA 模式適用于業(yè)務流程中的某些操作失敗后,可以通過補償機制修復的場景。
4. XA 模式(原生分布式事務)
XA 模式是傳統(tǒng)的分布式事務協(xié)議,它基于 XA協(xié)議,是一種強一致性的分布式事務模式。Seata 的 XA 模式要求參與者支持 XA 事務協(xié)議,例如數(shù)據(jù)庫、消息隊列等。
特點:
- 強一致性:XA 模式是最嚴格的分布式事務協(xié)議,確保所有分布式事務的最終一致性。
- 兩階段提交協(xié)議(2PC):與 AT 模式類似,XA 模式也采用了 2PC 協(xié)議來管理事務一致性。
- 依賴于底層數(shù)據(jù)庫的支持:必須使用支持 XA 事務的數(shù)據(jù)庫(例如,MySQL、Oracle 等)。
工作原理:
- 第一階段(Prepare):所有參與者準備提交事務,但不提交。
- 第二階段(Commit/Rollback):如果所有參與者都準備好,則提交事務,否則回滾事務。
適用場景:
- 嚴格要求強一致性的場景:例如銀行轉(zhuǎn)賬等對事務一致性要求極高的業(yè)務。
總結
Seata 支持以下四種分布式事務模式:
- AT 模式:適用于標準的數(shù)據(jù)庫操作,自動管理事務,適合不涉及復雜業(yè)務邏輯的場景。
- TCC 模式:適用于跨多個服務的復雜業(yè)務,需要手動編寫補償邏輯。
- SAGA 模式:適用于長事務,適合拆分為多個子事務的場景,每個子事務都可以獨立回滾。
- XA 模式:嚴格一致性的分布式事務協(xié)議,適用于需要強一致性的場景,如金融交易等。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決idea中maven項目打包成jar報錯:沒有主清單屬性的問題
這篇文章主要給大家分享了idea中maven項目打包成jar,報錯沒有主清單屬性解決方法,文中有詳細的解決方法,如果又遇到同樣問題的朋友可以參考一下本文2023-09-09java聯(lián)調(diào)生成測試數(shù)據(jù)工具類方式
這篇文章主要介紹了java聯(lián)調(diào)生成測試數(shù)據(jù)工具類方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03spring通過filter,Interceptor統(tǒng)一處理ResponseBody的返回值操作
這篇文章主要介紹了spring通過filter,Interceptor統(tǒng)一處理ResponseBody的返回值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09解析Oracle數(shù)據(jù)庫中的對象集合schema
這篇文章主要介紹了Oracle數(shù)據(jù)庫中的對象集合schema,是Oracle數(shù)據(jù)庫入門學習中的基礎知識,需要的朋友可以參考下2015-11-11