MySQL的鎖設計是為了在多用戶環(huán)境中管理對數(shù)據(jù)庫數(shù)據(jù)的并發(fā)訪問宛畦,確保數(shù)據(jù)的完整性和一致性,提供了大概12種鎖揍移,每一種鎖對應的業(yè)務場景不一樣次和,肖哥帶你掌握他的使用技巧。
1那伐、讀鎖/共享鎖(S鎖)
流程圖
image.png
- 設計目的:允許多個事務并發(fā)讀取同一資源踏施,提高系統(tǒng)的并發(fā)性能。
- 解決問題:防止臟讀罕邀。
- 使用場景:用戶查詢銀行賬戶余額畅形,同時不希望阻止其他用戶查詢。
- 業(yè)務案例:在線教育平臺诉探,當教師查詢學生的成績記錄時日熬,多個教師可以同時訪問成績,但不允許修改肾胯。
- MySQL操作案例:
SELECT * FROM accounts WHERE user_id = 'user1' LOCK IN SHARE MODE;
2竖席、寫鎖/排它鎖/獨占鎖(X鎖)
流程圖
image.png
- 設計目的:確保在數(shù)據(jù)被修改時,其他事務不能讀取或修改該數(shù)據(jù)阳液。
- 解決問題:防止不可重復讀和幻讀怕敬。
- 使用場景:用戶更新銀行賬戶余額,需要確保更新期間數(shù)據(jù)不被其他事務干擾帘皿。
- 業(yè)務案例:電子商務平臺东跪,在處理用戶訂單時,當訂單狀態(tài)需要被更新時鹰溜,需要確保在更新過程中數(shù)據(jù)的一致性虽填。
- MySQL操作案例:
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 'user1';
COMMIT;
3、意向鎖(Intention Locks)
流程圖
image.png
- 設計目的:在多粒度鎖定系統(tǒng)中曹动,用于表明事務在更高層次上的鎖定意圖斋日。
- 解決問題:協(xié)調(diào)行鎖和表鎖之間的關系。
- 使用場景:事務需要在表的多行上設置鎖墓陈,但表已被其他事務鎖定恶守。
- 業(yè)務案例:金融交易系統(tǒng)第献,在進行大規(guī)模數(shù)據(jù)報表生成時,需要在表級別表明鎖定意圖兔港,以協(xié)調(diào)行鎖和表鎖庸毫。
- MySQL操作案例: 意向鎖通常由MySQL自動處理,不需要用戶顯式操作衫樊。
4飒赃、自增鎖(Auto-increment Locks)
流程圖
image.png
- 設計目的:確保自增字段在并發(fā)插入時能夠生成唯一的序列號。
- 解決問題:防止自增字段的沖突科侈。
- 使用場景:在插入新用戶記錄時自動分配唯一ID载佳。
- 業(yè)務案例:社交媒體平臺,在創(chuàng)建新的帖子時臀栈,需要為每個帖子分配一個唯一的標識符蔫慧。
- MySQL操作案例:
INSERT INTO users (username) VALUES ('new_user');
5、 悲觀鎖(Pessimistic Locks)
流程圖
image.png
- 設計目的:在事務可能發(fā)生沖突的環(huán)境中挂脑,通過鎖定資源來保證數(shù)據(jù)一致性藕漱。
- 解決問題:避免數(shù)據(jù)競爭欲侮。
- 使用場景:銀行轉賬崭闲,需要確保資金的準確性和一致性。
- 業(yè)務案例:銀行系統(tǒng)威蕉,在處理資金轉賬時刁俭,為了避免并發(fā)操作導致的數(shù)據(jù)不一致,采取悲觀鎖策略韧涨。
- MySQL操作案例:
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
6牍戚、樂觀鎖(Optimistic Locks)
流程圖
image.png
- 設計目的:在沖突較少的環(huán)境中,通過檢測數(shù)據(jù)在讀取后是否被修改來避免鎖的開銷虑粥。
- 解決問題:減少鎖的使用如孝,提高系統(tǒng)性能。
- 使用場景:在線票務系統(tǒng)娩贷,用戶查看票務信息后決定是否購買第晰。
- 業(yè)務案例:在線協(xié)作文檔編輯,當多個用戶可以同時編輯同一文檔時彬祖,使用版本號來確保操作的一致性茁瘦。
- MySQL操作案例: 樂觀鎖通常通過應用程序邏輯實現(xiàn),例如使用數(shù)據(jù)表中的版本號或時間戳字段储笑。
- 初始讀取記錄 - 應用程序讀取記錄以及版本號甜熔。
SELECT id, data_column, version_column FROM table_name WHERE id = record_id;
這里,data_column
是你想要讀取的數(shù)據(jù)列突倍,version_column
是用于樂觀鎖的版本號列腔稀。
- 更新記錄 - 應用程序在本地進行更改盆昙,并嘗試更新數(shù)據(jù)庫中的記錄,同時檢查版本號是否一致焊虏。
UPDATE table_name
SET data_column = new_data_value,
version_column = version_column + 1
WHERE id = record_id
AND version_column = original_version_value;
在這個例子中弱左,new_data_value
是應用程序更新后的值,original_version_value
是最初讀取的版本號炕淮。如果version_column
在嘗試更新時沒有改變拆火,這條語句會成功更新記錄并增加版本號。如果版本號已經(jīng)改變(意味著另一個事務已經(jīng)更新了記錄)涂圆,這個更新就不會執(zhí)行们镜。
- 檢查更新是否成功 - 應用程序檢查更新操作是否影響了預期數(shù)量的行。
-- 這通常在應用程序邏輯中處理润歉,例如:
IF (update_affected_rows > 0) THEN
-- 更新成功模狭,版本號增加
ELSE
-- 更新失敗,版本號未改變踩衩,可能需要重新讀取記錄或拋出異常
END IF;
7嚼鹉、間隙鎖(Gap Lock)
流程圖
image.png
- 設計目的:防止幻讀,確保范圍查詢的一致性驱富。
- 解決問題:避免在鎖定范圍內(nèi)插入新記錄锚赤。
- 使用場景:適用于需要在某個范圍內(nèi)進行范圍查詢并保證結果一致性的情況。
- 業(yè)務案例: 銀行賬戶交易記錄查詢褐鸥,需要確保在查詢的日期范圍內(nèi)线脚,不會有新的交易記錄被插入,從而保證查詢結果的一致性叫榕。
- MySQL操作案例: 間隙鎖通常在執(zhí)行范圍查詢并加鎖時隱式使用浑侥,例如:
SELECT * FROM table_name WHERE column_name BETWEEN val1 AND val2 LOCK IN SHARE MODE;
這個查詢會鎖定val1
和val2
之間的所有記錄,并且防止其他事務在這個范圍內(nèi)插入新記錄晰绎。
8寓落、頁鎖(Page Lock)
流程圖
image.png
- 設計目的:鎖定數(shù)據(jù)庫頁,以減少鎖的粒度荞下。
- 解決問題:在行鎖和表鎖之間提供一種折中的鎖定策略伶选。
- 使用場景:適用于對表的某個部分進行操作,而不需要鎖定整個表锄弱。
- 業(yè)務案例:數(shù)據(jù)庫維護任務考蕾,如索引重建,需要對表的特定部分進行鎖定会宪,以減少對整個表的影響肖卧。
- MySQL操作案例: 頁鎖通常由InnoDB自動使用,不需要顯式的SQL操作掸鹅。但是塞帐,可以通過指定行鎖來間接使用頁鎖拦赠。
9、MDL鎖(Metadata Lock)
流程圖
image.png
- 設計目的:鎖定數(shù)據(jù)庫對象的元數(shù)據(jù)葵姥。
- 解決問題:防止在執(zhí)行某些操作時元數(shù)據(jù)被更改荷鼠。
- 使用場景:適用于修改表結構或統(tǒng)計信息收集等操作。
- 業(yè)務案例:數(shù)據(jù)庫管理員在調(diào)整數(shù)據(jù)庫結構榔幸,如添加新列或索引允乐,以確保結構變更期間數(shù)據(jù)定義的一致性。
- MySQL操作案例: MDL鎖由MySQL自動管理削咆,例如:
ALTER TABLE table_name ADD COLUMN new_column datatype;
這個操作會隱式地使用MDL鎖牍疏。
10、RL鎖(Record Lock)
流程圖
image.png
- 設計目的:鎖定單個記錄拨齐。
- 解決問題:確保單個記錄的一致性和完整性鳞陨。
- 使用場景:適用于需要更新單個記錄并保證更新期間記錄不被其他事務更改的情況
- 業(yè)務案例:電子商務網(wǎng)站在處理訂單,需要鎖定特定訂單記錄瞻惋,以確保訂單信息在處理過程中不被其他操作更改厦滤。
- MySQL操作案例:
SELECT * FROM table_name WHERE id = record_id FOR UPDATE;
這個查詢會鎖定指定ID的記錄,防止其他事務修改它歼狼。
11掏导、GL鎖(Gap Lock)
流程圖
image.png
- 設計目的:鎖定一個范圍內(nèi)的記錄,但不包括記錄本身蹂匹。
- 解決問題:防止在范圍內(nèi)插入新記錄碘菜,解決幻讀問題。
- 使用場景:適用于需要保證某個范圍內(nèi)數(shù)據(jù)一致性的情況限寞。
- 業(yè)務案例:股票交易系統(tǒng),在查詢某個價格區(qū)間內(nèi)的股票記錄時仰坦,需要防止新的交易記錄在該價格區(qū)間內(nèi)被插入履植。
- MySQL操作案例: GL鎖通常在執(zhí)行范圍查詢并加共享鎖時隱式使用,例如:
SELECT * FROM table_name WHERE column_name > val LOCK IN SHARE MODE;
這個查詢會鎖定大于val
的所有記錄悄晃,但不包括val
本身的記錄玫霎。
12、NKL鎖(Next-Key Lock)
流程圖
image.png
- 設計目的:結合了記錄鎖和間隙鎖的特性妈橄。
- 解決問題:同時防止在同一記錄上發(fā)生沖突和在范圍內(nèi)插入新記錄庶近。
- 使用場景:適用于需要同時保證記錄一致性和范圍一致性的情況。
- 業(yè)務案例:在線預訂系統(tǒng)眷蚓,在查詢并鎖定特定日期的房間時鼻种,需要同時防止該日期的房間被其他用戶預訂,以及防止在相鄰日期插入新的預訂記錄沙热。
- MySQL操作案例: NKL鎖通常由InnoDB自動使用叉钥,不需要顯式的SQL操作罢缸。例如,在執(zhí)行以下查詢時:
SELECT * FROM table_name WHERE column_name = val FOR UPDATE;
歷史熱點文章
- 外觀模式(Facade Pattern):微服務架構中的數(shù)據(jù)庫訪問實戰(zhàn)案例分析
- 代理模式(Proxy Pattern):權限校驗API調(diào)用實戰(zhàn)案例分析
- 橋接模式(Bridge Pattern):多樣式用戶界面組件實戰(zhàn)案例分析
- 組合模式(Composite Pattern): 在線教育平臺課程管理實戰(zhàn)案例分析
- 享元模式(Flyweight Pattern):網(wǎng)頁游戲中的角色對象管理實戰(zhàn)案例分析
- 觀察者模式(Observer Pattern):股票交易系統(tǒng)實戰(zhàn)案例分析
- 策略模式(Strategy Pattern):電商平臺的優(yōu)惠券系統(tǒng)實戰(zhàn)案例分析
- 模板方法模式(Template Method Pattern):視頻播放應用實戰(zhàn)案例分析
- 命令模式(Command Pattern):網(wǎng)絡爬蟲任務隊列實戰(zhàn)案例分析
- 迭代器模式(Iterator Pattern):電商平臺商品分類瀏覽實戰(zhàn)案例分析
- 中介者模式(Mediator Pattern):即時通訊軟件實戰(zhàn)案例分析
- 備忘錄模式(Memento Pattern):游戲存檔系統(tǒng)實戰(zhàn)案例分析
- 狀態(tài)模式(State Pattern):電商平臺訂單狀態(tài)管理實戰(zhàn)案例分析
- 責任鏈模式(Chain of Responsibility Pattern):電商平臺的訂單審批流程實戰(zhàn)案例分析
- 訪問者模式(Visitor Pattern):電商平臺商品訪問統(tǒng)計實戰(zhàn)案例分析
- 工廠方法模式(Factory Method Pattern): 電商多種支付實戰(zhàn)案例分析
- 抽象工廠模式(Abstract Factory Pattern):多風格桌面應用實戰(zhàn)案例分析
- 建造者模式(Builder Pattern): 在線訂單系統(tǒng)實戰(zhàn)案例分析
- 原型模式(Prototype Pattern): 云服務環(huán)境配置實戰(zhàn)案例分析
- 適配器模式(Adapter Pattern):第三方支付集成實戰(zhàn)案例分析
- 裝飾器模式(Decorator Pattern):電商平臺商品價格策略實戰(zhàn)案例分析
- 單例模式(Singleton Pattern):購物車實戰(zhàn)案例分析