日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分布式事务中间件Fescar—全局写排它锁解读

發(fā)布時間:2025/4/16 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式事务中间件Fescar—全局写排它锁解读 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

一般,數(shù)據(jù)庫事務的隔離級別會被設置成?讀已提交,已滿足業(yè)務需求,這樣對應在Fescar中的分支(本地)事務的隔離級別就是?讀已提交,那么Fescar中對于全局事務的隔離級別又是什么呢?如果認真閱讀了?分布式事務中間件Txc/Fescar-RM模塊源碼解讀?的同學應該能推斷出來:Fescar將全局事務的默認隔離定義成讀未提交。對于讀未提交隔離級別對業(yè)務的影響,想必大家都比較清楚,會讀到臟數(shù)據(jù),經(jīng)典的就是銀行轉(zhuǎn)賬例子,出現(xiàn)數(shù)據(jù)不一致的問題。而對于Fescar,如果沒有采取任何其它技術手段,那會出現(xiàn)很嚴重的問題,比如:

如上圖所示,問最終全局事務A對資源R1應該回滾到哪種狀態(tài)?很明顯,如果再根據(jù)UndoLog去做回滾,就會發(fā)生嚴重問題:覆蓋了全局事務B對資源R1的變更。那Fescar是如何解決這個問題呢?答案就是?Fescar的全局寫排它鎖解決方案,在全局事務A執(zhí)行過程中全局事務B會因為獲取不到全局鎖而處于等待狀態(tài)。
對于Fescar的隔離級別,引用官方的一段話來作說明:

全局事務的隔離性是建立在分支事務的本地隔離級別基礎之上的。
在數(shù)據(jù)庫本地隔離級別?讀已提交?或以上的前提下,Fescar 設計了由事務協(xié)調(diào)器維護的?全局寫排他鎖,來保證事務間的?寫隔離,將全局事務默認定義在?讀未提交?的隔離級別上。
我們對隔離級別的共識是:絕大部分應用在?讀已提交?的隔離級別下工作是沒有問題的。而實際上,這當中又有絕大多數(shù)的應用場景,實際上工作在?讀未提交?的隔離級別下同樣沒有問題。
在極端場景下,應用如果需要達到全局的?讀已提交,Fescar 也提供了相應的機制來達到目的。默認,Fescar 是工作在?讀未提交?的隔離級別下,保證絕大多數(shù)場景的高效性。

下面,本文將深入到源碼層面對Fescar全局寫排它鎖實現(xiàn)方案進行解讀。Fescar全局寫排它鎖實現(xiàn)方案在TC(Transaction Coordinator)模塊維護,RM(Resource Manager)模塊會在需要鎖獲取全局鎖的地方請求TC模塊以保證事務間的寫隔離,下面就分成兩個部分介紹:TC-全局寫排它鎖實現(xiàn)方案、RM-全局寫排它鎖使用

一、TC—全局寫排它鎖實現(xiàn)方案
首先看一下TC模塊與外部交互的入口,下圖是TC模塊的main函數(shù):

上圖中看出RpcServer處理通信協(xié)議相關邏輯,而對于TC模塊真實處理器是DefaultCoordiantor,里面包含了所有TC對外暴露的功能,比如doGlobalBegin(全局事務創(chuàng)建)、doGlobalCommit(全局事務提交)、doGlobalRollback(全局事務回滾)、doBranchReport(分支事務狀態(tài)上報)、doBranchRegister(分支事務注冊)、doLockCheck(全局寫排它鎖校驗)等,其中doBranchRegister、doLockCheck、doGlobalCommit就是全局寫排它鎖實現(xiàn)方案的入口。

/**
* 分支事務注冊,在注冊過程中會獲取分支事務的全局鎖資源
*/
@Override
protected void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RpcContext rpcContext) throws TransactionException {
? ? response.setTransactionId(request.getTransactionId());
? ? response.setBranchId(core.branchRegister(request.getBranchType(), request.getResourceId(), rpcContext.getClientId(),
? ? ? ? ? ? XID.generateXID(request.getTransactionId()), request.getLockKey()));
}
/**
* 校驗全局鎖能否被獲取到
*/
@Override
protected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response, RpcContext rpcContext)
? ? throws TransactionException {
? ? response.setLockable(core.lockQuery(request.getBranchType(), request.getResourceId(),
? ? ? ? XID.generateXID(request.getTransactionId()), request.getLockKey()));
}
/**
* 全局事務提交,會將全局事務下的所有分支事務的鎖占用記錄釋放
*/
@Override
protected void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response, RpcContext rpcContext)
throws TransactionException {
? ?response.setGlobalStatus(core.commit(XID.generateXID(request.getTransactionId())));
}
上述代碼邏輯最后會被代理到DefualtCore去做執(zhí)行

如上圖,不管是獲取鎖還是校驗鎖狀態(tài)邏輯,最終都會被LockManger所接管,而LockManager的邏輯由DefaultLockManagerImpl實現(xiàn),所有與全局寫排它鎖的設計都在DefaultLockManagerImpl中維護。
首先,就先來看一下全局寫排它鎖的結(jié)構:

private static final ConcurrentHashMap<String, ConcurrentHashMap<String, ConcurrentHashMap<Integer, Map<String, Long>>>> LOCK_MAP = new ConcurrentHashMap<~>();


整體上,鎖結(jié)構采用Map進行設計,前半段采用ConcurrentHashMap,后半段采用HashMap,最終其實就是做一個鎖占用標記:在某個ResourceId(數(shù)據(jù)庫源ID)上某個Tabel中的某個主鍵對應的行記錄的全局寫排它鎖被哪個全局事務占用。下面,我們來看一下具體獲取鎖的源碼:

如上圖注釋,整個acquireLock邏輯還是很清晰的,對于分支事務需要的鎖資源,要么是一次性全部成功獲取,要么全部失敗,不存在部分成功部分失敗的情況。通過上面的解釋,可能會有兩個疑問:

為什么鎖結(jié)構前半部分采用ConcurrentHashMap,后半部分采用HashMap?
前半部分采用ConcurrentHashMap好理解:為了支持更好的并發(fā)處理;疑問的是后半部分為什么不直接采用ConcurrentHashMap,而采用HashMap呢?可能原因是因為后半部分需要去判斷當前全局事務有沒有占用PK對應的鎖資源,是一個復合操作,即使采用ConcurrentHashMap還是避免不了要使用Synchronized加鎖進行判斷,還不如直接使用更輕量級的HashMap。

為什么BranchSession要存儲持有的鎖資源
這個比較簡單,在整個鎖的結(jié)構中未體現(xiàn)分支事務占用了哪些鎖記錄,這樣如果全局事務提交時,分支事務怎么去釋放所占用的鎖資源呢?所以在BranchSession保存了分支事務占用的鎖資源。

下圖展示校驗全局鎖資源能否被獲取邏輯:

下圖展示分支事務釋放全局鎖資源邏輯

以上就是TC模塊中全局寫排它鎖的實現(xiàn)原理:在分支事務注冊時,RM會將當前分支事務所需要的鎖資源一并傳遞過來,TC獲取負責全局鎖資源的獲取(要么一次性全部成功,要么全部失敗,不存在部分成功部分失敗);在全局事務提交時,TC模塊自動將全局事務下的所有分支事務持有的鎖資源進行釋放;同時,為減少全局寫排它鎖獲取失敗概率,TC模塊對外暴露了校驗鎖資源能否被獲取接口,RM模塊可以在在適當位置加以校驗,以減少分支事務注冊時失敗概率。

二、RM-全局寫排它鎖使用
在RM模塊中,主要使用了TC模塊全局鎖的兩個功能,一個是校驗全局鎖能否被獲取,一個是分支事務注冊去占用全局鎖,全局鎖釋放跟RM無關,由TC模塊在全局事務提交時自動釋放。分支事務注冊前,都會去做全局鎖狀態(tài)校驗邏輯,以保證分支注冊不會發(fā)生鎖沖突。
在執(zhí)行Update、Insert、Delete語句時,都會在sql執(zhí)行前后生成數(shù)據(jù)快照以組織成UndoLog,而生成快照的方式基本上都是采用Select...For Update形式,RM嘗試校驗全局鎖能否被獲取的邏輯就在執(zhí)行該語句的執(zhí)行器中:SelectForUpdateExecutor,具體如下圖:

基本邏輯如下:

執(zhí)行Select ... For update語句,這樣本地事務就占用了數(shù)據(jù)庫對應行鎖,其它本地事務由于無法搶占本地數(shù)據(jù)庫行鎖,進而也不會去搶占全局鎖。
循環(huán)掌握校驗全局鎖能否被獲取,由于全局鎖可能會被先于當前的全局事務獲取,因此需要等之前的全局事務釋放全局鎖資源;如果這里校驗能獲取到全局鎖,那么由于步驟1的原因,在當前本地事務結(jié)束前,其它本地事務是不會去獲取全局鎖的,進而保證了在當前本地事務提交前的分支事務注冊不會因為全局鎖沖突而失敗。
注:細心的同學可能會發(fā)現(xiàn),對于Update、Delete語句對應的UpdateExecutor、DeleteExecutor中會因獲取beforeImage而執(zhí)行Select..For Update語句,進而會去校驗全局鎖資源狀態(tài),而對于Insert語句對應的InsertExecutor卻沒有相關全局鎖校驗邏輯,原因可能是:因為是Insert,那么對應插入行PK是新增的,全局鎖資源必定未被占用,進而在本地事務提交前的分支事務注冊時對應的全局鎖資源肯定是能夠獲取得到的。

接下來我們再來看看分支事務如何提交,對于分支事務中需要占用的全局鎖資源如何生成和保存的。首先,在執(zhí)行SQL完業(yè)務SQL后,會根據(jù)beforeImage和afterImage生成UndoLog,與此同時,當前本地事務所需要占用的全局鎖資源標識也會一同生成,保存在ContentoionProxy的ConnectionContext中,如下圖所示。


在ContentoionProxy.commit中,分支事務注冊時會將ConnectionProxy中的context內(nèi)保存的需要占用的全局鎖標識一同傳遞給TC進行全局鎖的獲取。

以上,就是RM模塊中對全局寫排它鎖的使用邏輯,因在真正執(zhí)行獲取全局鎖資源前會去循環(huán)校驗全局鎖資源狀態(tài),保證在實際獲取鎖資源時不會因為鎖沖突而失敗,但這樣其實壞處也很明顯:在鎖沖突比較嚴重時,會增加本地事務數(shù)據(jù)庫鎖占用時長,進而給業(yè)務接口帶來一定的性能損耗。

三、總結(jié)
本文詳細介紹了Fescar為在?讀未提交?隔離級別下做到?寫隔離?而實現(xiàn)的全局寫排它鎖,包括TC模塊內(nèi)的全局寫排它鎖的實現(xiàn)原理以及RM模塊內(nèi)如何對全局寫排它鎖的使用邏輯。在了解源碼過程中,筆者也遺留了兩個問題:

全局寫排它鎖數(shù)據(jù)結(jié)構保存在內(nèi)存中,如果服務器重啟/宕機了怎么辦,即TC模塊的高可用方案是什么呢?
一個Fescar管理的全局事務和一個非Fescar管理的本地事務之間發(fā)生鎖沖突怎么辦?具體問題如下圖,問題是:全局事務A如何回滾?
對于問題1有待繼續(xù)研究;對于問題2目前已有答案,但Fescar目前暫未實現(xiàn),具體就是全局事務A回滾時會報錯,全局事務A內(nèi)的分支事務A1回滾時會校驗afterImage與當前表中對應行數(shù)據(jù)是否一致,如果一致才允許回滾,不一致則回滾失敗并報警通知對應業(yè)務方,由業(yè)務方自行處理。

?
?

轉(zhuǎn)載于:https://my.oschina.net/xiaominmin/blog/3041672

總結(jié)

以上是生活随笔為你收集整理的分布式事务中间件Fescar—全局写排它锁解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品国产电影 | 久色综| 国产香蕉久久 | 亚洲理伦| 九色影院| 中国一级特黄毛片大片 | 亚洲AV无码成人精品区明星换面 | 色婷婷在线视频 | 91在线观看 | 国产极品一区二区 | 国产精品欧美一区喷水 | 自拍视频网址 | 岛国伊人| 国产精品一区久久久 | 夜夜操夜夜干 | 男人舔女人下部高潮全视频 | 99riav3国产精品视频 | 黄色在线资源 | 日韩精品成人无码专区免费 | 激情av| 色啪综合| 亚洲制服在线观看 | 91性色| 爽爽视频在线观看 | 欧美精品在线视频观看 | 天堂成人在线 | 国产激情av一区二区三区 | 国产一区二区激情 | 青青草超碰在线 | 欧美精品黑人猛交高潮 | 天天综合久久综合 | 午夜院线| 超碰视屏| 亚洲av日韩av永久无码下载 | 精品在线观看视频 | 黄色av网址在线观看 | 成人性视频sm.| 欧美人与性动交g欧美精器 国产在线视频91 | 91蝌蚪少妇偷拍 | 激情综合在线 | 一级毛片儿| av成人在线播放 | 午夜色网站 | 成人自拍网 | 91看片视频 | 色姑娘综合网 | 在线天堂网 | 羞羞答答一区 | 人人爽人人插 | av观看网 | 视频免费观看在线 | 午夜激情毛片 | 91免费视频网 | 九九热视频精品 | 黄片毛片视频 | 日韩五码电影 | 中文在线中文资源 | 久久综合在线 | 久久黄色录像 | 国产av成人一区二区三区高清 | 91在线日本 | 古装做爰无遮挡三级视频 | 成人av高清 | 亚拍一区 | 欧美成人综合色 | 国产精品69毛片高清亚洲 | 亚洲激情av | 外国黄色网址 | 91丨porny丨成人蝌蚪 | 99精品欧美一区二区三区 | www亚洲一区| 五月婷婷伊人网 | 青青草55| 婷婷玖玖 | 中文字幕亚洲专区 | 免费网站在线观看视频 | 四虎精品在永久在线观看 | 中文高清av | 久久免费视频1 | 成人亚洲精品久久久久软件 | 人妻少妇被粗大爽9797pw | 重口另类 | 久久天天躁狠狠躁夜夜av | 亚洲一区二区三区四区在线观看 | 成人观看视频 | 欧美日一区二区 | 亚洲天堂不卡 | 欧美不卡| 一区二区三区在线观 | 久久久久久久精 | 黄网站免费在线观看 | 亚洲天堂一区 | 成人av免费网址 | 哪里可以看毛片 | 99精品视频在线看 | 曰批免费视频播放免费 | 黄色性生活一级片 | 亚洲精品午夜精品 | 日本免费一区二区三区四区 |