MYSQL悲觀鎖及樂觀鎖方式
MySQL支持兩種鎖機(jī)制:悲觀鎖和樂觀鎖。
悲觀鎖
悲觀鎖是指在執(zhí)行讀寫操作之前先獲取鎖,保證在操作完成之前其他線程無法修改數(shù)據(jù)。
舉個例子:
假設(shè)有一個銀行轉(zhuǎn)賬的業(yè)務(wù)場景,其中涉及到兩個賬戶的金額操作,為了避免數(shù)據(jù)沖突和并發(fā)問題,可以采用悲觀鎖來實現(xiàn)。
悲觀鎖在MySQL中主要有兩種實現(xiàn)方式:
1.通過SELECT ... FOR UPDATE語句實現(xiàn)
該語句可以將待更新的行加鎖,保證其他事務(wù)無法在該行加鎖之前對其進(jìn)行修改操作。
例如:
假設(shè)有一個用戶表,其中每個用戶有一個余額字段,現(xiàn)在需要將某個用戶的余額減少100元,可以使用以下SQL語句:
BEGIN; SELECT balance FROM user WHERE id = 1 FOR UPDATE; UPDATE user SET balance = balance - 100 WHERE id = 1; COMMIT;
在這個例子中:
通過SELECT ... FOR UPDATE語句先對待更新的用戶行加鎖,確保其他事務(wù)無法在執(zhí)行更新操作之前對其進(jìn)行修改。
2.通過LOCK TABLES語句實現(xiàn)
該語句可以將整個表或者表中的某些行加鎖,確保其他事務(wù)無法對其進(jìn)行修改操作。
例如,假設(shè)有一個訂單表,其中每個訂單有一個狀態(tài)字段,現(xiàn)在需要將所有未付款的訂單狀態(tài)改為已付款,可以使用以下SQL語句:
LOCK TABLES order WRITE; UPDATE order SET status = 1 WHERE status = 0; UNLOCK TABLES;
在這個例子中:
通過LOCK TABLES語句將整個訂單表加鎖,確保其他事務(wù)無法對其進(jìn)行修改,然后執(zhí)行更新操作,最后使用UNLOCK TABLES語句釋放鎖。
需要注意的是,悲觀鎖機(jī)制在實現(xiàn)上通常需要使用到數(shù)據(jù)庫的鎖機(jī)制,因此在高并發(fā)場景下可能會導(dǎo)致性能瓶頸和死鎖問題,所以需要謹(jǐn)慎使用。
樂觀鎖
MySQL中的樂觀鎖機(jī)制是指在執(zhí)行讀寫操作之前不加鎖,而是通過版本號或者時間戳等機(jī)制判斷數(shù)據(jù)是否被其他事務(wù)修改過,從而決定是否執(zhí)行寫操作。相比于悲觀鎖,樂觀鎖的優(yōu)勢在于減少了鎖等待和死鎖等問題,提高了并發(fā)性能。
下面舉例說明MySQL數(shù)據(jù)庫中的樂觀鎖機(jī)制。
假設(shè)有一個用戶表,其中每個用戶有一個余額字段。
現(xiàn)在需要對某個用戶的余額進(jìn)行修改,如果余額值不變,則可以直接更新;否則需要重新讀取最新的余額值并判斷是否可以更新。
可以使用以下SQL語句實現(xiàn):
UPDATE user SET balance = balance - 100 WHERE id = 1 AND balance >= 100;
在這個例子中:
通過在更新語句中加入AND balance >= 100的條件,確保只有余額大于等于100的用戶才能被更新。
如果在執(zhí)行更新操作之前,其他事務(wù)修改了該用戶的余額值,那么執(zhí)行該更新語句時不會更新任何數(shù)據(jù)。
這樣就避免了臟數(shù)據(jù)和并發(fā)問題,同時也避免了使用悲觀鎖帶來的性能問題。
需要注意的是:
- 在使用樂觀鎖機(jī)制時,需要特別關(guān)注并發(fā)沖突的問題。
- 如果并發(fā)沖突較為頻繁,那么樂觀鎖可能會導(dǎo)致較高的重試率和性能損失。因此,樂觀鎖更適合于并發(fā)沖突較少的場景。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL Innodb關(guān)鍵特性之插入緩沖(insert buffer)
這篇文章主要介紹了MySQL Innodb關(guān)鍵特性之插入緩沖的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Innodb存儲引擎,感興趣的朋友可以了解下2021-04-04
Mysql將查詢結(jié)果集轉(zhuǎn)換為JSON數(shù)據(jù)的實例代碼
這篇文章主要介紹了Mysql將查詢結(jié)果集轉(zhuǎn)換為JSON數(shù)據(jù)的實例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
搞定mysql行轉(zhuǎn)列的7種方法以及列轉(zhuǎn)行
在MySQL數(shù)據(jù)庫中,有時候我們需要將一列數(shù)據(jù)轉(zhuǎn)化為行數(shù)據(jù),以便更好地進(jìn)行數(shù)據(jù)分析和處理,下面這篇文章主要給大家介紹了關(guān)于搞定mysql行轉(zhuǎn)列的7種方法以及列轉(zhuǎn)行的相關(guān)資料,需要的朋友可以參考下2024-03-03
MySQL中使用case when 語句實現(xiàn)多條件查詢的方法
今天在一個應(yīng)用中使用到了一個比較特殊的數(shù)據(jù)查詢要求。需要的朋友可以參考下。2010-12-12

