XA事務與MySQL


XA事務就是兩階段提交的一種實現方式

XA規范主要定義了事務管理器TM,和資源管理器RM之間的接口

根據2PC的規范,將一次事務分割成兩個階段

1. prepare階段

TM向所有RM發送prepare指令,RM接受到指令后執行數據修改和日志記錄等操作,然后返回 可以提交/不可提交 給TM

(按照我的理解應該類似於MySQL在開啟一個事務之后,只差最后的COMMIT或者ROLLBACK的狀態)

2. commit階段

TM接受到所有RM的prepare結果

如果有RM返回是 不可提交 或者超時,那么向所有RM發送ROLLBACK命令

如果所有RM都返回可以提交,那么向所有RM發送COMMIT命令

 

XA的異常情況處理

 

 

MySQL與XA事務的關系有兩種情況

1. 內部XA

在使用innodb作為存儲引擎,並且開啟binlog的情況下,MySQL同時維護了binlog日志與innodb的redo log

為了保證這兩個日志的一致性,MySQL使用了XA事務,由於只在單機上工作,所以被稱為內部XA

2. 外部XA

就是一般談論的分布式事務了

MySQL支持XA START/END/PREPARE/COMMIT這些sql語句,通過使用這些命令,我們是可以完成分布式事務的

狀態轉移圖如下

 (我有點不能理解的是,為什么一定需要XA END這個語句,直接XA PREPARE不行嗎)

在MySQL5.7.7之前,XA事務是有bug的

如果有一個XA事務處於PREPARE狀態

1. 如果連接關閉,或者MySQL服務器正常退出,這個事務會被回滾(但是根據XA規范,這個事務應該被保留)

2. 如果MySQL服務器被強制結束,在重啟之后,用XA RECOVER命令可以看到這個事務,這個事務也可以被XA COMMIT所提交,但是相關的binlog記錄會丟失,這樣就會導致數據庫引擎中的數據與binlog中的數據不一致   (參考資料

這兩個bug被提出了十年之久,終於在5.7.7中被修正了第一個bug阿里自己也搞了個修正

就目前來看,MySQL的XA事務現在做得還不錯,應該是可用的

 

還是有一些不能理解的地方

1. 官方文檔中強調:在使用分布式事務的時候,需要使用串行隔離級別,為什么?

(As with nondistributed transactions, SERIALIZABLE may be preferred if your applications are sensitive to read phenomena. REPEATABLE READ may not be sufficient for distributed transactions.)

 原因:為了盡可能提高分布式事物的隔離級別,如果分庫上使用MySQL默認的RR,那么導致總的分布式事務的隔離級別為RU

 

 

 

參考資料

1. MySQL binlog 組提交與 XA(兩階段提交)

2. MySQL redolog與組提交 資料1 資料2 資料3 資料4

3. MySQL官方的XA文檔

4. XA事務的隔離級別


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM