什么是Seata分布式事務(wù)解決方案
Seata是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù)。為用戶提供了AT、TCC、SAGA和XA事務(wù)模式,為用戶打造一站式的分布式解決方案。
AT模式
AT模式目前來看是Seata框架獨(dú)有的一種模式,其它的分布式框架上并沒有此種模式的實(shí)現(xiàn)。其是由二階段提交演變來的,解決了二階段提交的同步阻塞等問題。
演變后的兩階段提交協(xié)議:
- 一階段:業(yè)務(wù)數(shù)據(jù)和回滾日志記錄在同一個(gè)本地事務(wù)中提交,釋放本地鎖和連接資源。
- 二階段:
- 提交異步化,非??焖俚赝瓿?。
- 回滾通過一階段的回滾日志進(jìn)行反向補(bǔ)償。
Seata框架中有三個(gè)概念要闡述下。
- TC:事務(wù)協(xié)調(diào)器,它是獨(dú)立的組件,需要獨(dú)立部署運(yùn)行,Seata提供了這個(gè)獨(dú)立運(yùn)行的程序,它負(fù)責(zé)維護(hù)全局事務(wù)的運(yùn)行狀態(tài),接收TM指令發(fā)起全局事務(wù)的提交與回滾,負(fù)責(zé)與RM通信,協(xié)調(diào)各個(gè)分支事務(wù)的提交或回滾。
- TM:事務(wù)管理器,TM需要嵌入應(yīng)用程序,它負(fù)責(zé)開啟一個(gè)全局事務(wù),并定義全局事務(wù)的范圍,它的目的是最終向TC發(fā)起全局提交或回滾指令。
- RM:與TC通信,控制分支事務(wù),負(fù)責(zé)分支注冊(cè)、報(bào)告分支事務(wù)狀態(tài),并接收事務(wù)協(xié)調(diào)器TC的指令,命令分支事務(wù)完成本地事務(wù)的提交或回滾。
流程示意圖如下:
這個(gè)圖還是比較清晰地,建議是先好好的理解下全流程。
Seata AT模式的具體流程如下。
(1)訂單服務(wù)收到請(qǐng)求,訂單服務(wù)中的TM向TC申請(qǐng)開啟一個(gè)全局事務(wù)。(2)TC收到請(qǐng)求,創(chuàng)建一個(gè)全局事務(wù),并將全局事務(wù)ID(稱為XID)返回給訂單服務(wù)的TM。
(3)訂單服務(wù)的RM向TC注冊(cè)分支事務(wù)。
(4)訂單服務(wù)執(zhí)行本地分支事務(wù)的業(yè)務(wù)邏輯并提交,釋放鎖定的數(shù)據(jù)庫資源。
(5)訂單服務(wù)向TC上報(bào)本地分支事務(wù)的提交結(jié)果。
(6)訂單服務(wù)調(diào)用遠(yuǎn)程的積分服務(wù),此時(shí)將XID通過參數(shù)傳給積分服務(wù)。(7)積分服務(wù)向TC注冊(cè)分支事務(wù)。
(8)積分服務(wù)執(zhí)行本地分支事務(wù)的業(yè)務(wù)邏輯并提交,釋放鎖定的數(shù)據(jù)庫資源,并返回訂單服務(wù)。
(9)積分服務(wù)向TC上報(bào)本地分支事務(wù)的提交結(jié)果。
(10)訂單服務(wù)的TM向TC發(fā)起全局事務(wù)的提交或回滾。
(11)TC向XID管轄下的全部分支事務(wù)發(fā)出提交或回滾的指令。
實(shí)現(xiàn)原理
我個(gè)人覺得框架其實(shí)也是一種需求的兌現(xiàn),只是不像平常開發(fā)時(shí)那樣有產(chǎn)品經(jīng)理給你輸出需求文檔(應(yīng)該也會(huì)有,但是少),業(yè)務(wù)流程不是傳統(tǒng)的那種XXX業(yè)務(wù),框架的需求一般是偏向技術(shù)一些,我把它認(rèn)為是技術(shù)需求;而日常我們做的開發(fā)一般是業(yè)務(wù)需求的兌現(xiàn)。
上面的流程可以看作是需求,那么現(xiàn)在需求出來了,程序猿要怎么實(shí)現(xiàn)?
設(shè)計(jì)思路
TM的設(shè)計(jì)
流程的開始與結(jié)束是由TM決定的,這個(gè)TM就是訂單服務(wù)Controller入口進(jìn)去后的某個(gè)Service方法(當(dāng)然也可能不是,看你的代碼架構(gòu),我這里只按照我自己的平常的開發(fā)模式來。)在這個(gè)Service方法中,處理了訂單服務(wù)以及積分服務(wù)的業(yè)務(wù)。當(dāng)Service方法完成后,那么就是整個(gè)業(yè)務(wù)做完了,事務(wù)即完成。因此,要我來實(shí)現(xiàn),這個(gè)TM對(duì)應(yīng)的Service方法,我會(huì)選擇用一個(gè)注解包裹,通過動(dòng)態(tài)代理的方式,在這個(gè)方法的前后分別負(fù)責(zé)全局事務(wù)的開始與結(jié)束流程。
RM的設(shè)計(jì)
RM負(fù)責(zé)執(zhí)行具體的業(yè)務(wù),將數(shù)據(jù)入庫同時(shí)上報(bào)給TC。由于二階段回滾時(shí)需要根據(jù)回滾日志replay,那么就一定需要記錄業(yè)務(wù)數(shù)據(jù)執(zhí)行的日志。那怎么記錄?回想了下Mybatis中的數(shù)據(jù)源代理,這里也是一樣的思路。必須攔截或是代理原先的數(shù)據(jù)源,解析原執(zhí)行的sql,注入Seata的邏輯,增強(qiáng)其執(zhí)行邏輯。我們看下RM要做的事情,第一階段:
第二階段提交:
第二階段回滾:
在執(zhí)行sql的過程中,各個(gè)代理對(duì)象起到的作用如下
所以在RM端最關(guān)鍵的就是數(shù)據(jù)源代理以及遠(yuǎn)程通信。這兩塊尤其是前者,就是AT模式的技術(shù)實(shí)現(xiàn)。
TC的設(shè)計(jì)
TC端需要管理Seata全局事務(wù)會(huì)話信息,一般是由全局事務(wù)、分支事務(wù)、全局鎖構(gòu)成,對(duì)應(yīng)表globaltable、branchtable、lock_table。因此在安裝部署的時(shí)候(file模式除外)都會(huì)創(chuàng)建這三個(gè)表。從上面來看,目前我們還沒有實(shí)現(xiàn)隔離性,所謂的隔離性是指多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫時(shí),數(shù)據(jù)庫為每個(gè)用戶開啟的事務(wù)不能被其他事務(wù)的操作所干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。這也是這里有一個(gè)全局鎖表的原因。每次本地事務(wù)提交前,都會(huì)向TC端申請(qǐng)注冊(cè)分支,同時(shí)還會(huì)申請(qǐng)全局鎖,RM端通過拿到的全局鎖保證了讀寫的隔離性,因此一旦當(dāng)前事務(wù)持有全局鎖,那么其他的事務(wù)不能提交。
寫隔離
兩個(gè)全局事務(wù) tx1 和 tx2,分別對(duì) a 表的 m 字段進(jìn)行更新操作,m 的初始值 1000。
- tx1 先開始,開啟本地事務(wù),拿到本地鎖,更新操作 m = 1000 - 100 = 900。本地事務(wù)提交前,先拿到該記錄的全局鎖 ,本地提交釋放本地鎖。
- tx2 后開始,開啟本地事務(wù),拿到本地鎖,更新操作 m = 900 - 100 = 800。本地事務(wù)提交前,嘗試拿該記錄的全局鎖,tx1 全局提交前,該記錄的全局鎖被 tx1 持有,tx2 需要重試等待全局鎖。
- tx1 二階段全局提交,釋放全局鎖。tx2 拿到全局鎖提交本地事務(wù)。
如果 tx1 的二階段全局回滾,則 tx1 需要重新獲取該數(shù)據(jù)的本地鎖,進(jìn)行反向補(bǔ)償?shù)母虏僮鳎瑢?shí)現(xiàn)分支的回滾。
此時(shí),如果 tx2 仍在等待該數(shù)據(jù)的全局鎖,同時(shí)持有本地鎖,則 tx1 的分支回滾會(huì)失敗。分支的回滾會(huì)一直重試,直到 tx2 的全局鎖等鎖超時(shí),放棄全局鎖并回滾本地事務(wù)釋放本地鎖,tx1 的分支回滾最終成功。
因?yàn)檎麄€(gè)過程全局鎖在 tx1 結(jié)束前一直是被 tx1 持有的,所以不會(huì)發(fā)生臟寫的問題。
讀隔離
seata at 模式默認(rèn)的隔離級(jí)別為讀未提交(因?yàn)橐呀?jīng)提交的sql有可能會(huì)回滾)。如果要實(shí)現(xiàn)讀已提交,select語句需要更改為 SELECT FOR UPDATE 語句。
SELECT FOR UPDATE 語句的執(zhí)行會(huì)申請(qǐng)全局鎖,如果全局鎖被其他事務(wù)持有,則釋放本地鎖(回滾 SELECT FOR UPDATE 語句的本地執(zhí)行)并重試。這個(gè)過程中,查詢是被 block 住的,直到 全局鎖 拿到,即讀取的相關(guān)數(shù)據(jù)是已提交的,才返回。
總結(jié)
Seata AT可以給你帶來一種“無侵入”式的編程體驗(yàn),你不需要改動(dòng)任何業(yè)務(wù)代碼,只需要一個(gè)注解和少量的配置信息,就可以實(shí)現(xiàn)分布式事務(wù)。文章來源:http://www.zghlxwxcb.cn/news/detail-451387.html
總結(jié)來看,AT模式主要是是基于 DataSource 代理實(shí)現(xiàn)的,通過代理 DataSource、Connection、PreparedStatement,攔截 SQL 執(zhí)行,增強(qiáng)其執(zhí)行邏輯,由代理側(cè)加入額外的能力以提供分布式事務(wù)服務(wù)類似自動(dòng)擋駕駛模式,分布式事務(wù)這個(gè)強(qiáng)大且復(fù)雜的服務(wù)能力由Seata框架托管,對(duì)業(yè)務(wù)實(shí)現(xiàn)無侵入式,用戶仍然只專注于業(yè)務(wù) SQL。文章來源地址http://www.zghlxwxcb.cn/news/detail-451387.html
到了這里,關(guān)于聊聊Seata分布式解決方案AT模式的實(shí)現(xiàn)原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!