MySQL對(duì)于各種鎖的概念理解
樂(lè)觀鎖
樂(lè)觀鎖大多是基于數(shù)據(jù)版本記錄機(jī)制實(shí)現(xiàn),一般是給數(shù)據(jù)庫(kù)表增加一個(gè)"version"字段。讀取數(shù)據(jù)時(shí),將此版本號(hào)一同讀出,之后更新時(shí),對(duì)此版本號(hào)加一。此時(shí)將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫(kù)表對(duì)應(yīng)記錄的當(dāng)前版本信息進(jìn)行比對(duì),如果提交的數(shù)據(jù)版本號(hào)大于數(shù)據(jù)庫(kù)表當(dāng)前版本號(hào),則予以更新,否則認(rèn)為是過(guò)期數(shù)據(jù)。
比如下單操作:
查詢出商品信息。
select (quantity, version) from t_goods where id = #{id}
根據(jù)商品信息生成訂單。
將商品數(shù)量減1。
update t_goods set quantity = quantity - 1 where id = #{id} and version = #{version}
悲觀鎖
悲觀鎖依靠數(shù)據(jù)庫(kù)提供的鎖機(jī)制實(shí)現(xiàn)。MySQL中的共享鎖和排它鎖都是悲觀鎖。數(shù)據(jù)庫(kù)的增刪改操作默認(rèn)都會(huì)加排他鎖,而查詢不會(huì)加任何鎖。
共享鎖(讀鎖)
共享鎖指的就是對(duì)于多個(gè)不同的事務(wù),對(duì)于一個(gè)資源共享同一個(gè)鎖。對(duì)某一資源加共享鎖,自身可可讀該資源,其他人也可以讀該資源(也可以再加共享鎖,即共享鎖共享多個(gè)內(nèi)存),但無(wú)法修改。要想修改就必須等所有共享鎖都釋放完之后。語(yǔ)法:select * from table lock in share mode;
。
比如:
窗口1,在一個(gè)未結(jié)束的事務(wù)中給一條數(shù)據(jù)加上共享鎖。
BEGIN; SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口2,給同一條數(shù)據(jù)加上共享鎖,加鎖成功。
SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口1和窗口2,更新該行數(shù)據(jù),提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction
。需要等到所有共享鎖釋放,才可以進(jìn)行update操作。
UPDATE t_red_packet SET user_id = 2
排它鎖(寫(xiě)鎖)
排它鎖指的就是對(duì)于多個(gè)不同的事務(wù),對(duì)同一個(gè)資源只能有一把鎖。對(duì)某一資源加排它鎖,自身可以進(jìn)行增刪改查,其他人無(wú)法進(jìn)行加鎖操作,更無(wú)法進(jìn)行增刪改操作。語(yǔ)法:select * from table for update
。
窗口1,在一個(gè)未結(jié)束的事務(wù)中給一條數(shù)據(jù)加上排它鎖。
BEGIN; SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
窗口1,更新該行數(shù)據(jù),成功。
UPDATE t_red_packet SET user_id = 2
窗口2,查詢?cè)撔袛?shù)據(jù),可以查詢到。
SELECT * FROM t_red_packet WHERE id = 1
窗口2給該條數(shù)據(jù)加鎖,提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction
。
SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
綜上,共享鎖就是大家一起來(lái)讀,一起來(lái)共享鎖,但誰(shuí)都不要對(duì)鎖著的數(shù)據(jù)進(jìn)行修改,排它鎖就是我自己就是想來(lái)修改,你們可以讀,但你們都不能到鎖,也不能對(duì)數(shù)據(jù)進(jìn)行修改。
行鎖
行鎖就是給一行數(shù)據(jù)進(jìn)行加鎖。
表鎖
表鎖就是對(duì)一張表進(jìn)行加鎖。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
mysql too many open connections問(wèn)題解決方法
這篇文章主要介紹了mysql too many open connections問(wèn)題解決方法,其實(shí)是max_connections配置問(wèn)題導(dǎo)致,它必須在[mysqld]下面才會(huì)生效,需要的朋友可以參考下2014-05-05Navicat導(dǎo)入導(dǎo)出Mysql?結(jié)構(gòu)、數(shù)據(jù)、結(jié)構(gòu)+數(shù)據(jù)完整步驟
導(dǎo)出表結(jié)構(gòu)是指將數(shù)據(jù)庫(kù)中的表的結(jié)構(gòu)信息導(dǎo)出為SQL腳本或其他格式的文件,這個(gè)功能非常實(shí)用,特別是在數(shù)據(jù)庫(kù)遷移或備份時(shí),這篇文章主要給大家介紹了關(guān)于Navicat導(dǎo)入導(dǎo)出Mysql?結(jié)構(gòu)、數(shù)據(jù)、結(jié)構(gòu)+數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2024-08-08為什么MySQL選擇Repeatable Read作為默認(rèn)隔離級(jí)別
關(guān)于MySQL的事務(wù)隔離級(jí)別,相信很多讀者都不陌生,那么,你知道為什么Oracle選擇RC作為默認(rèn)級(jí)別,而MySQL要選擇RR作為默認(rèn)的隔離級(jí)別嗎2021-07-07mysql5.7單實(shí)例自啟動(dòng)服務(wù)配置過(guò)程
這篇文章主要介紹了mysql5.7單實(shí)例自啟動(dòng)服務(wù)配置的過(guò)程,附含配置源碼,有需要的朋友可以借鑒參考下,希望可以有所幫助,感謝閱讀2021-09-09Mysql刪除重復(fù)數(shù)據(jù)并且只保留一條(附實(shí)例!)
最近有朋友打電話尋求一個(gè)SQL相關(guān)的問(wèn)題,大致是表中存在重復(fù)數(shù)據(jù),需要?jiǎng)h除掉重復(fù)數(shù)據(jù)保留一條的場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于Mysql刪除重復(fù)數(shù)據(jù)并且只保留一條的相關(guān)資料,需要的朋友可以參考下2023-02-02mysql運(yùn)行net start mysql報(bào)服務(wù)名無(wú)效的解決辦法
這篇文章主要為大家詳細(xì)介紹了mysql運(yùn)行net start mysql報(bào)服務(wù)名無(wú)效的解決辦法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01史上最簡(jiǎn)單的MySQL數(shù)據(jù)備份與還原教程(上)(三十五)
這篇文章主要為大家詳細(xì)介紹了史上最簡(jiǎn)單的MySQL數(shù)據(jù)備份與還原教程第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10