前言
mysql支持單機(jī)事務(wù)的良好表現(xiàn)毋庸置疑,那么在分布式系統(tǒng)中,涉及多個(gè)節(jié)點(diǎn),mysql又是如何實(shí)現(xiàn)分布式事務(wù)的呢?比如開發(fā)一個(gè)業(yè)務(wù)系統(tǒng),它接受外部的請(qǐng)求,然后訪問多個(gè)內(nèi)部其它系統(tǒng)才能執(zhí)行該請(qǐng)求。執(zhí)行時(shí)我們需要同時(shí)更新多個(gè)數(shù)據(jù)庫的值(d1,d2,d3)。由于系統(tǒng)必須處于一個(gè)一致性,也就是這三個(gè)數(shù)據(jù)庫的值要么同時(shí)更新成功,要么全部不更新。不然會(huì)造成子系統(tǒng)有些指令成功了,有些指令尚未執(zhí)行。導(dǎo)致對(duì)結(jié)果理解混亂。
那么,mysql如何實(shí)現(xiàn)多個(gè)mysql數(shù)據(jù)庫更新的一致性呢?那就是mysql xa。mysql正是靠支持xa規(guī)范的二階段提交協(xié)議,才實(shí)現(xiàn)了多個(gè)數(shù)據(jù)庫的操作。
xa 協(xié)議
提到xa規(guī)范就得來聊一下dtp模型(distributed transaction processing)。xa規(guī)范就是約定dtp模型中的兩個(gè)模塊事務(wù)管理器和資源管理器的通訊方式。dtp其實(shí)就是分布式事務(wù)處理
各個(gè)模塊的作用如下:
- ap(application program):應(yīng)用程序,定義事務(wù)邊界(定義事務(wù)開始和結(jié)束)并訪問事務(wù)邊界內(nèi)的資源。
- rm(resource manger)資源管理器: 管理共享資源并提供外部訪問接口。供外部程序來訪問數(shù)據(jù)庫等共享資源。此外,rm還具有事務(wù)的回滾能力。
- tm(transaction manager)事務(wù)管理器:tm是分布式事務(wù)的協(xié)調(diào)者,tm與每個(gè)rm進(jìn)行通信,負(fù)責(zé)管理全局事務(wù),分配事務(wù)唯一標(biāo)識(shí),監(jiān)控事務(wù)的執(zhí)行進(jìn)度,并負(fù)責(zé)事務(wù)的提交、回滾、失敗恢復(fù)等。
剛開始看可能覺得不好理解,總結(jié)起來該架構(gòu)就是應(yīng)用程序訪問及使用資環(huán)管理器提供的共享資源,通過事務(wù)管理器提供的事務(wù)接口(tx interface)定義事務(wù)操作。事務(wù)管理器和資源管理會(huì)基于xa規(guī)范執(zhí)行二階段提交協(xié)議。
xa規(guī)范流程如下圖所示
- 應(yīng)用程序ap向事務(wù)管理器tm發(fā)起事務(wù)請(qǐng)求
- tm調(diào)用xa_open()建立同資源管理器的會(huì)話
- tm調(diào)用xa_start()標(biāo)記一個(gè)事務(wù)分支的開頭
- ap訪問資源管理器rm并定義操作,比如插入記錄操作
- tm調(diào)用xa_end()標(biāo)記事務(wù)分支的結(jié)束
- tm調(diào)用xa_prepare()通知rm做好事務(wù)分支的提交準(zhǔn)備工作。其實(shí)就是二階段提交的提交請(qǐng)求階段。
- tm調(diào)用xa_commit()通知rm提交事務(wù)分支,也就是二階段提交的提交執(zhí)行階段。
-
tm調(diào)用xa_close管理與rm的會(huì)話。
- 這些接口一定要按順序執(zhí)行,比如xa_start接口一定要在xa_end之前。此外,這里千萬要注意的是事務(wù)管理器只是標(biāo)記事務(wù)分支并不執(zhí)行事務(wù),事務(wù)操作最終是由應(yīng)用程序通知資源管理器完成的。另外,我們來總結(jié)下xa的接口
- xa_start:負(fù)責(zé)開啟或者恢復(fù)一個(gè)事務(wù)分支,并且管理xid到調(diào)用線程
- xa_end:負(fù)責(zé)取消當(dāng)前線程與事務(wù)分支的關(guān)系
- xa_prepare:負(fù)責(zé)詢問rm 是否準(zhǔn)備好了提交事務(wù)分支 xa_commit:通知rm提交事務(wù)分支
- xa_rollback:通知rm回滾事務(wù)分支
如何通過mysql xa實(shí)現(xiàn)分布式事務(wù)
mysql中存在兩種xa事務(wù),一種是內(nèi)部xa事務(wù)主要用來協(xié)調(diào)存儲(chǔ)引擎和二進(jìn)制日志,一種是外部事務(wù)可以參與到外部分布式事務(wù)中(比如多個(gè)數(shù)據(jù)庫實(shí)現(xiàn)的分布式事務(wù)),這里我們主要討論外部事務(wù)。
注:mysql中只有當(dāng)隔離級(jí)別設(shè)置為serializable的時(shí)候才能使用分布式事務(wù)。
mysql的xa語法如下
1
2
3
4
5
6
|
xa {start| begin } xid [ join |resume] xa prepare xid xa end xid xa commit xid[one phase] xa rollback xid xa recover[ convert xid ] |
其中xid作為事務(wù)id,唯一表示一個(gè)事務(wù)分支,每個(gè)事務(wù)分支都有一個(gè)id。
首先要確認(rèn)是否開啟了xa 功能
設(shè)置隔離級(jí)別為serializable
執(zhí)行結(jié)果
首先調(diào)用“xa start ‘xid' ”命令把xa事務(wù)置于activate狀態(tài),接著執(zhí)行構(gòu)成事務(wù)的多條sql語句(比如 update
t1 set c1 = ‘a' where id=1),也就是指定事務(wù)的邊界。然后調(diào)用“xa end ‘xid' ”把事務(wù)放入idle狀態(tài),也就是結(jié)束事務(wù)邊界。
接著,對(duì)于一個(gè)處于idle狀態(tài)的xa事務(wù),可以執(zhí)行“xa prepare”命令或一個(gè)“xa commit…one phase”命令,xa
prepare來執(zhí)行二階段提交協(xié)議的提交請(qǐng)求階段。執(zhí)行“xa recover”命令會(huì)列出處于prepared狀態(tài)的所有xa事務(wù)。xa
commit…one phase用于預(yù)備和提交事務(wù),也就是轉(zhuǎn)換為一階段協(xié)議,直接提交事務(wù)。
最后,調(diào)用“xa commit”來提交事務(wù)(或者“xa rollback”回滾事務(wù))。這樣就實(shí)現(xiàn)了全局事務(wù)的一致性了。
通過上面的流程可以看到,在mysql數(shù)據(jù)庫分布式事務(wù)中,mysql的角色其實(shí)是xa事務(wù)過程中的rm,tm是連接mysql服務(wù)器的客戶端。在分布式事務(wù)中一般會(huì)涉及到至少兩個(gè)rm,所以我們說的mysql支持xa協(xié)議是說mysql作為rm來說的,也就是說mysql實(shí)現(xiàn)了xa協(xié)議中rm應(yīng)該具有的功能。
到此這篇關(guān)于一文搞懂mysql xa如何實(shí)現(xiàn)分布式事務(wù)的文章就介紹到這了,更多相關(guān)mysql xa分布式事務(wù)內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.csdn.net/songguangfan/article/details/121194345