若是說在 TiDB 3.0 中,悲觀鎖是 「千呼萬喚始出來,猶抱琵琶半遮面」。那麼在 TiDB 4.0 中,悲觀鎖在經歷了市場與時光的考驗後,不管是性能仍是穩定性都可以 「輕攏慢撚抹復挑,初爲《霓裳》後《六幺》」。TiDB 4.0 悲觀鎖,歡迎你們嚐鮮與反饋。本文將從使用者的角度,介紹悲觀鎖的使用與注意事項,主要分爲如下幾方面:mysql
自新年以來,口罩做爲 2020 年最時尚的年貨,變得異常難買,爲了可以順利搶到口罩,我是夜夜展轉難眠,日日盯着各大網站下單,經過這個過程,倒也總結出了各大平臺的的購物體驗:sql
做爲互聯網研發從業者,聰慧如你,一塊兒來思考這兩類網站是如何實現加購物車這一邏輯?數據庫
A 類網站樂觀地假設不存在其餘客戶同時搶這批口罩,庫存表明沒下單的庫存,給了客戶很是積極的體驗,咱們稱這種行爲下加購物車時,使用了樂觀鎖。性能優化
這種樂觀鎖使用的體驗是:前期加購物車一時爽,最終下單可不必定爽。session
當存在其餘網友同時跟你搶這批口罩下單時,可能會遇到如下問題:併發
B 類網站可謂謹言慎行,假設全部在別人家購物車裏的口罩都會先於你下單,展現給你的庫存是在當前最壞場景下可以看到的庫存,咱們稱這種行爲下加購物車時,使用了悲觀鎖。分佈式
如上悲觀鎖的體驗是:前期加購物車有點卡,可是加購物車成功必定有庫存。沒有庫存莫着急,等一下子再來可能又有庫存了。性能
在數據庫的實現中,當同時存在多個事務去修改同一行時,也會遇到相似衝突問題,經過實現悲觀鎖,能夠解決部分樂觀鎖的問題,重點以下:優化
TiDB 支持多種方式打開悲觀鎖,具體信息見官方文檔, 本文將以如下方式爲例展開介紹:網站
BEGIN PESSIMISTIC;
語句開啓的事務,會進入悲觀事務模式。BEGIN /*!90000 PESSIMISTIC */;
來兼容 MySQL 語法。以下圖, 縱軸表示時間軸,session A 和 session B 併發更新同一行數據。
能夠看到悲觀鎖的行爲以下:
上例展現的悲觀鎖事務與 MySQL 行爲一致,理解以下:
在看這個例子以前,咱們首先思考一下爲何會有死鎖,一樣以購物爲例子,假設如今小 A 和小 B 兩人都要買口罩和消毒水,可能遇到如下場景:
也就是 A 和 B 兩位都要買到這兩個商品,只能一直互相等待,也就是咱們說的進入死鎖狀態,在數據庫也是相似:
上例展現的場景中 session A 和 session B 產生了死鎖,在產生死鎖時,悲觀鎖會當即檢測到並返回錯誤,將死鎖扼殺在搖籃裏。
做爲分佈式數據庫 TiDB 一直努力與 MySQL 保持協議上的兼容,以造福廣大 MySQL 用戶。然而 TiDB 與 MySQL 底層實現邏輯的區別,使得部分邏輯沒法作到徹底兼容。在 TiDB 4.0 中,TiDB 悲觀鎖與 MySQL 在使用上不兼容的行爲詳見 官方文檔 ,這裏咱們簡要介紹如下幾點。
當沒法保證符合過濾條件的數據惟一時:
具體對好比下表所示(注:table 中 id 爲主鍵):
TiDB 中執行 DML 過程當中包若是包含 embedded select select,對應的行不會被加鎖,MySQL 則會進行加鎖。
事務做爲數據庫的重中之重,一直是大衆關注的焦點。TiDB 自誕生以來便以支持高性能的分佈式事務而聞名。本文從使用者的角度,介紹了 TiDB 4.0 中悲觀鎖的使用與注意事項,歡迎你們嚐鮮與反饋。
將來,咱們會給出更多 TiDB 悲觀鎖實現原理與性能優化相關的介紹,歡迎你們持續關注。同時,TiDB 分佈式事務將來還有更多激動人心的改進等着你們來一塊兒完成,歡迎你們一塊兒來監督來幫忙來提高,調研與實踐國際一流的分佈式事務模型。更多反饋歡迎發送至 transaction-group@pingcap.com。