Fescar鎖和隔離級別的理解

銅板街技術發表於2019-01-31

Fescar全域性鎖的理解

前幾天夜裡,我老大發我一篇文章說阿里的GTS開源了。 因為一直對分散式事務比較感興趣,立馬pull了程式碼,進行閱讀。基本的原理,實現方案我就不一一細化了,詳細見官方文件(寫的很棒,點贊)。

在fescar的社群,大家比較關注的是通過fescar回滾到before快照前,別的執行緒假如更新了資料,且業務走完了,那麼恢復的這個快照不就是髒資料了麼。 很顯然,這種情況在fescar中是不被允許的。

那麼fescar是如何做的呢?

我們先簡單瞭解一下fescar的設計原理

那些一上來就喜歡看原始碼的同學,一定不要錯過這麼官方的圖文介紹,看完再讀原始碼事半功倍。

Fescar官方介紹(https://github.com/alibaba/fescar/wiki)

瞭解完Fescar的基本原理,我們重點關注下Fescar的全域性排他鎖

Fescar設計了一個全域性的排他鎖,來保證事務間的 寫隔離。

關於隔離性:(這是Fescar官方給的一段話)

全域性事務的隔離性是建立在分支事務的本地隔離級別基礎之上的。

在資料庫本地隔離級別 讀已提交或以上 的前提下,Fescar 設計了由事務協調器維護的 全域性寫排他鎖,來保證事務間的 寫隔離,將 全域性事務預設定義在 讀未提交 的隔離級別上

我們對隔離級別的共識是:絕大部分應用在讀已提交的隔離級別下工作是沒有問題的。而實際上,這當中又有絕大多數的應用場景,實際上工作在讀未提交的隔離級別下同樣沒有問題。

在極端場景下,應用如果需要達到全域性的讀已提交,Fescar也提供了相應的機制來達到目的。 預設,Fescar 是工作在 讀無提交 的隔離級別下,保證絕大多數場景的高效性。

我的解讀

本地事務【讀已提交】,fescar全域性事務【讀未提交】。這是這段話的核心。 我理解的這段話中fescar全域性事務讀未提交,並不是說本地事務的db資料沒有正常提交,而是指全域性事務二階段commit|rollback未真正處理完(即未釋放全域性鎖)。

總結來說:全域性未提交但是本地已提交的資料,對其他全域性事務是可見的【當然在本地事務提交後,本地事務提交前,隔離級別是本地事務的管轄範圍】

for example 產品份額有5W,A使用者購買了2萬,份額branch一階段完畢(本地事務份額已經扣除commit),但是在下單的時候異常了。 因為本地事務讀已提交,這時候fescar允許業務訪問該條資料,3W,在A使用者的份額branch未回滾成功前,對其他使用者可見。 但是其他使用者並不能買該產品,必須等到產品份額回滾到5萬,其他使用者才可以操作產品資料。

所以看了這個例子 真的有必要做到全域性事務讀已提交麼?

我們先來看一下Fescar的全域性鎖的做法

Fescar一階段

1. 本地(Branch)在向TC註冊的時候,把本地事務需要修改的資料table+pks提交到server端申請鎖,拿到全域性鎖後,才能提交本地事務

2. 全域性鎖的結構:resourceId + table + pks

3. 鎖是存在server端 branchSession中

Fescar二階段

一階段本地事務提交,db的鎖釋放了(for update鎖),但是全域性鎖繼續保持, 直到二階段決議(注意釋放鎖的順序):

1. 提交:TC 釋放鎖,通知branch提交後 (rm端非同步處理)

2. 回滾:TC 通知branch回滾後,釋放鎖(rm端同步處理 執行undo_log)

Fescar如何保障鎖的高效?

大家自己先思考下,最後給大家仔細解讀官方的demo,並分析fescar的效能問題。

Fescar目前開源版本全域性鎖的實現

大家有興趣自己閱讀:com.alibaba.fescar.server.lock.DefaultLockManagerImpl

官方的圖實在是做的太漂亮了,clone一份解讀 TC TM RM 以及全域性鎖的獲取和釋放動作發生點

分支事務如何工作?關注全域性鎖的獲取和釋放 特別是二階段commit和rollback全域性鎖釋放的順序

Fescar鎖和隔離級別的理解

Fescar中 RM TM TC如何工作的?

Fescar鎖和隔離級別的理解

看了這兩張圖,大家應該對fescar是如何工作的應該有一個大致的瞭解了。☺

1. 全域性鎖的獲取

2. tm tc rm之間如何通訊工作

3. 隔離級別問題的思考

最後我們來解讀一遍官方的demo

  • branch1:update storage

    tbl set count = count - ? where commodity
    code = ?

  • branch2:update account

    tbl set money = money - ? where user
    id = ?

  • branch3:insert into order

    tbl (user
    id, commodity_code, count, money) values (?, ?, ?, ?)

1. 執行緒A:執行branch1(pk:55),執行branch2的時候發現沒錢了,扔了一個異常,那麼勢必需要回滾branch1的份額。

  • TM通知TC開始回滾branch1份額中

2. 執行緒B:執行branch1(pk:55)

  • 如果執行緒A中branch1(pk:55)已經回滾成功了,那麼B執行緒可以正常拿到鎖走下去

  • 如果執行緒A中branch1還未回滾(resourceId+table+pk鎖未釋放)。當執行緒B發起branch1向server發起申請鎖,會直接失敗。

Fescar全域性鎖簡單總結:操作一條記錄的分支事務,必須等待這條記錄的前一個分支事務執行結束(具體commit rollback情況分析如下),才能持有鎖。

其實相比XA的鎖,fescar在每個分支事務的一階段結束後都釋放了db的鎖,所以fescar的效能瓶頸應該在於二階段的執行速度(釋放鎖的快慢)

因為分散式事務在執行事務編排前,一般會校驗業務的正確性,所以發生回滾的概率相對較低,所以先考慮二階段commit操作。

1. Commit場景分析:

TM通知server進行commit,server立馬釋 branch的鎖,然後再逐個通知RM提交 消耗:1 rpc操作,(branch刪除undo_log放在非同步佇列裡面做)

2. Rollback場景分析:

TM通知server進行rollback,server通知RM回滾後立馬釋放 branch的鎖。 消耗:1 + N的rpc操作 + N的回滾sql操作

所以總的來看fescar在commit的釋放全域性鎖還是非常高效的。

思考

1. server支援多臺機器部署,應該如何改造?

全域性鎖的問題,鎖改造; 全域性事務向server0申請的,Branch1發到server1,branch2發到server2的問題,多機器恢復的情況,TC的改造

2. 全域性鎖在Fescar中更新確實是沒有問題的,但是如果就是業務方需要手動調整DB資料呢 ?

大膽猜測,依賴Fescar寫了一個管理平臺 用來執行sql的。哈哈

3. 隔離級別的思考

Fescar預設工作在,本地事務讀已提交,全域性事務讀未提交。 是否存在全域性事務必須工作在【讀已提交】級別而不能工作在【讀未提交】的業務場景呢? 大家大膽腦洞 這個問題值得探討。

4. Fescar的文件中說,是支援全域性事務讀已提交的,那麼fescar是如何實現的呢?

感興趣的同學可以試著讀一下

com.alibaba.fescar.rm.datasource.exec.SelectForUpdateExecutor複製程式碼

原始碼核心類

大家想讀原始碼的話,可以重點關注一下幾個類。有問題一起探討。

TM相關

com.alibaba.fescar.tm.api.TransactionalTemplate
複製程式碼

RM相關

com.alibaba.fescar.rm.datasource.exec.SelectForUpdateExecutor
com.alibaba.fescar.rm.datasource.ConnectionProxy
com.alibaba.fescar.rm.datasource.exec.AbstractDMLBaseExecutor
com.alibaba.fescar.rm.RMHandlerAT
複製程式碼

TC相關

com.alibaba.fescar.server.coordinator.DefaultCoordinator
com.alibaba.fescar.server.coordinator.DefaultCore
com.alibaba.fescar.server.lock.DefaultLockManagerImpl
複製程式碼

- Github:https://github.com/alibaba/fescar

- 官方中文介紹:https://github.com/alibaba/fescar/wiki

作者簡介

雨人,銅板街交易團隊研發工程師,2016年5月加入銅板街,目前主要負責資金端專案的開發。


                                Fescar鎖和隔離級別的理解

                      更多精彩內容,請掃碼關注 “銅板街技術” 微信公眾號。 

相關文章