TiDB 4.0 新特性前瞻:白話 “悲觀鎖”
如果說在 TiDB 3.0 中,悲觀鎖是 “千呼萬喚始出來,猶抱琵琶半遮面”。那麼在 TiDB 4.0 中,悲觀鎖在經歷了市場與時光的考驗後,無論是效能還是穩定性都能夠 “輕攏慢撚抹復挑,初為《霓裳》後《六么》”。TiDB 4.0 悲觀鎖,歡迎大家嚐鮮與反饋。本文將從使用者的角度,介紹悲觀鎖的使用與注意事項,主要分為以下幾方面:
白話悲觀鎖
TiDB 悲觀鎖的使用和常見現象
TiDB 悲觀鎖與 MySQL 的相容性
未來展望
白話悲觀鎖
自新年以來,口罩作為 2020 年最時尚的年貨,變得異常難買,為了能夠順利搶到口罩,我是夜夜輾轉難眠,日日盯著各大網站下單,通過這個過程,倒也總結出了各大平臺的的購物體驗:
A 類網站:加購物車飛快,成功加入購物車加後,下單不一定有庫存。
B 類網站:加購物車有點卡,成功加入購物車後,下單一定有庫存。
作為網際網路研發從業者,聰慧如你,一起來思考這兩類網站是如何實現加購物車這一邏輯?
A 類網站樂觀地假設不存在其他客戶同時搶這批口罩,庫存代表沒下單的庫存,給了客戶非常積極的體驗,我們稱這種行為下加購物車時,使用了樂觀鎖。
這種樂觀鎖使用的體驗是:前期加購物車一時爽,最終下單可不一定爽。
當存在其他網友同時跟你搶這批口罩下單時,可能會遇到以下問題:
提交不一定成功。
衝突需要重試。(其他人先下單,庫存變化,需要重試)
衝突嚴重且重試代價大的場景(比方說你一次性買了一萬種商品)效能差,失敗率高。
B 類網站可謂謹言慎行,假設所有在別人家購物車裡的口罩都會先於你下單,展示給你的庫存是在當前最壞場景下能夠看到的庫存,我們稱這種行為下加購物車時,使用了悲觀鎖。
如上悲觀鎖的體驗是:前期加購物車有點卡,但是加購物車成功一定有庫存。沒有庫存莫著急,等一會兒再來可能又有庫存了。
在資料庫的實現中,當同時存在多個事務去修改同一行時,也會遇到類似衝突問題,通過實現悲觀鎖,可以解決部分樂觀鎖的問題,重點如下:
事務提交一定成功。
MySQL 預設支援悲觀鎖,支援了悲觀鎖意味著,MySQL 的客戶不需要修改任何程式碼,就可以輕鬆上船 TiDB。
TiDB 悲觀鎖的使用和常見現象
TiDB 支援多種方式開啟悲觀鎖,具體資訊見官方文件, 本文將以以下方式為例展開介紹:
執行
BEGIN PESSIMISTIC;
語句開啟的事務,會進入悲觀事務模式。註釋的形式
BEGIN /*!90000 PESSIMISTIC */;
來相容 MySQL 語法。
併發更新同一行資料
如下圖, 縱軸表示時間軸,session A 和 session B 併發更新同一行資料。
可以看到悲觀鎖的行為如下:
在 session B 執行 DML 時,發現同一行被 session A 鎖住,等待至 session A 提交才執行。
DML 執行成功後,最終 commit 也成功。
SELECT .. FOR UPDATE
上例展示的悲觀鎖事務與 MySQL 行為一致,理解如下:
純查詢語句的隔離級別為 SI 隔離級別,即讀取為事務 begin 時的版本資料。
SELECT .. FOR UPDATE 的隔離級別為 RC,即讀取為當前已提交的版本資料。
DEADLOCK
在看這個例子之前,我們首先思考一下為什麼會有死鎖,同樣以購物為例子,假設現在小 A 和小 B 兩人都要買口罩和消毒水,可能遇到以下場景:
也就是 A 和 B 兩位都要買到這兩個商品,只能一直互相等待,也就是我們說的進入死鎖狀態,在資料庫也是類似:
上例展示的場景中 session A 和 session B 產生了死鎖,在產生死鎖時,悲觀鎖會立即檢測到並返回錯誤,將死鎖扼殺在搖籃裡。
TiDB 悲觀鎖 VS MySQL InnoDB
作為分散式資料庫 TiDB 一直努力與 MySQL 保持協議上的相容,以造福廣大 MySQL 使用者。然而 TiDB 與 MySQL 底層實現邏輯的區別,使得部分邏輯無法做到完全相容。在 TiDB 4.0 中,TiDB 悲觀鎖與 MySQL 在使用上不相容的行為詳見 官方文件 ,這裡我們簡要介紹以下幾點。
TiDB 沒有間隙鎖
當無法保證符合過濾條件的資料唯一時:
MySQL 會鎖住過濾條件能涵蓋到的所有行:範圍鎖,全表鎖。
TiDB 只會對讀取到的行加鎖。
具體對比如下表所示(注:table 中 id 為主鍵):
embedded select 行為不一致
TiDB 中執行 DML 過程中包如果包含 embedded select select,對應的行不會被加鎖,MySQL 則會進行加鎖。
未來展望
事務作為資料庫的重中之重,一直是大眾關注的焦點。TiDB 自誕生以來便以支援高效能的分散式事務而聞名。本文從使用者的角度,介紹了 TiDB 4.0 中悲觀鎖的使用與注意事項,歡迎大家嚐鮮與反饋。
未來,我們會給出更多 TiDB 悲觀鎖實現原理與效能優化相關的介紹,歡迎大家持續關注。同時,TiDB 分散式事務未來還有更多激動人心的改進等著大家來一起完成,歡迎大家一起來監督來幫忙來提升,調研與實踐國際一流的分散式事務模型。更多反饋歡迎傳送至 transaction-group@pingcap.com。
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- TiDB 4.0 新特性前瞻(四)圖形化診斷介面TiDB
- TiDB 4.0 新特性嚐鮮指南TiDB
- TiDB 4.0 新特性前瞻(三)再也不用擔心我的 SQL 突然變慢了TiDBSQL
- 悲觀鎖和樂觀鎖
- laravel樂觀鎖和悲觀鎖Laravel
- mysql悲觀鎖以樂觀鎖MySql
- 理解樂觀鎖和悲觀鎖
- MySQL鎖(樂觀鎖、悲觀鎖、多粒度鎖)MySql
- java-樂觀鎖與悲觀鎖Java
- MybatisPlus - [03] 樂觀鎖&悲觀鎖MyBatis
- MySQL樂觀鎖和悲觀鎖介紹MySql
- Java中的鎖之樂觀鎖與悲觀鎖Java
- 面試必備之悲觀鎖與樂觀鎖面試
- Redis的事務、樂觀鎖和悲觀鎖Redis
- MySQL 悲觀鎖與樂觀鎖的詳解MySql
- 面試必備之樂觀鎖與悲觀鎖面試
- Java彌散系列 - 樂觀鎖與悲觀鎖Java
- SQLServer樂觀鎖定和悲觀鎖定例項SQLServer
- 樂觀鎖與悲觀鎖及應用舉例
- 資料庫中的悲觀鎖和樂觀鎖資料庫
- JPA和Hibernate的樂觀鎖與悲觀鎖
- 【鎖機制】共享鎖、排它鎖、悲觀鎖、樂觀鎖、死鎖等等
- 在MongoDB中使用悲觀鎖MongoDB
- oracle-- tom悲觀鎖演示Oracle
- 悲觀鎖定的應用
- Java 中的悲觀鎖和樂觀鎖的實現Java
- synchronized 作為悲觀鎖,鎖住了什麼?synchronized
- Mybatis Generator Plugin悲觀鎖實現MyBatisPlugin
- 利用MySQL中的樂觀鎖和悲觀鎖實現分散式鎖MySql分散式
- [轉帖]SQL Server 鎖機制 悲觀鎖 樂觀鎖 實測解析SQLServer
- 悲觀鎖與樂觀鎖的實現(詳情圖解)圖解
- 【每日鮮蘑】從資料庫看樂觀鎖、悲觀鎖資料庫
- 面試必備的資料庫悲觀鎖與樂觀鎖面試資料庫
- 小議“悲觀鎖和樂觀鎖”的原理、場景、示例
- 關於樂觀鎖與悲觀鎖的實際應用
- SSM (十五) 樂觀鎖與悲觀鎖的實際應用SSM
- 樂觀鎖和悲觀鎖策略的區別與實現
- SQL SERVER樂觀鎖定和悲觀鎖定使用例項SQLServer