MySQL悲觀鎖是什么?底層實現原理?
MySQL悲觀鎖經常在大廠被問到,比如MySQL悲觀鎖是什么?MySQL悲觀鎖有哪些?底層原理...等等,下面我來詳解MySQL悲觀鎖。
MySQL悲觀鎖
圖片
在 MySQL 中悲觀鎖(Pessimistic Lock),是一種并發控制機制,用于防止多個事務同時修改同一條數據,從而確保數據一致性。
基于“悲觀”的假設,認為在多用戶環境下,數據被多個事務同時訪問、或修改的沖突概率較高。
因此,在操作數據之前,先對數據加鎖,確保同一時刻只有一個事務能修改某條數據,避免臟讀、幻讀、丟失更新...等問題。
適用于 庫存扣減、訂單處理 ...等業務,防止庫存超賣、或數據篡改。
悲觀鎖的實現
1.行級鎖
MySQL悲觀鎖,依賴于數據庫提供的鎖機制來實現,比如:MySQL的InnoDB存儲引擎提供了行級鎖,用于實現悲觀并發控制。
常見的行級鎖包括 :SELECT ... FOR UPDATE,如下所示:
START TRANSACTION; -- 開啟事務
-- 查詢用戶余額,并加鎖,防止其他事務修改
SELECT balance FROM accounts WHERE user_id = 1 FOR UPDATE;
-- 更新用戶余額
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
COMMIT; -- 提交事務,釋放鎖
使用 SELECT ... FOR UPDATE 語句,對查詢的行,加排他鎖。
首先,事務 A ,先執行 SELECT ... FOR UPDATE,獲取寫鎖;
然后,事務 B 試圖執行 SELECT ... FOR UPDATE,會被阻塞,直到 事務 A 提交或回滾。
2.共享鎖
使用 SELECT ... LOCK IN SHARE MODE 語句對查詢的行加共享鎖,如下所示:
START TRANSACTION;
-- 查詢某個產品的庫存,并加共享鎖,防止其他事務修改
SELECT stock FROM products WHERE product_id = 1 LOCK IN SHARE MODE;
COMMIT;
適用于只讀操作,事務可以讀取數據并加共享鎖,其他事務仍能讀取數據,但不能修改,直到共享鎖釋放。
3.表級鎖
表級鎖:在事務操作過程中,對整張表進行鎖定,以保證在整個事務操作期間該表不被其他事務修改。
LOCK TABLES products READ; -- 對 products 表加讀鎖
SELECT * FROM products; -- 允許多個事務同時讀
-- 其他事務試圖 UPDATE、INSERT、DELETE products 表時,會被阻塞
UNLOCK TABLES; -- 釋放鎖
相比于 行級鎖(Row Lock),表級鎖的粒度較大,會鎖住整張表,從而降低了并發性能,但避免了死鎖問題。
在數據一致性非常重要的場景中,例如:金融交易、或庫存管理,悲觀鎖可以確保數據的準確性、和完整性,適合在并發量不高的環境。