MySQL數(shù)據(jù)庫(kù)鎖機(jī)制原理解析
在并發(fā)訪問情況下,很有可能出現(xiàn)不可重復(fù)讀等等讀現(xiàn)象。為了更好的應(yīng)對(duì)高并發(fā),封鎖、時(shí)間戳、樂觀并發(fā)控制(樂觀鎖)、悲觀并發(fā)控制(悲觀鎖)都是并發(fā)控制采用的主要技術(shù)方式。
鎖分類
①、按操作劃分:DML鎖,DDL鎖
②、按鎖的粒度劃分:表級(jí)鎖、行級(jí)鎖、頁(yè)級(jí)鎖
③、按鎖級(jí)別劃分:共享鎖、排他鎖
④、按加鎖方式劃分:自動(dòng)鎖、顯示鎖
⑤、按使用方式劃分:樂觀鎖、悲觀鎖
樂觀鎖和悲觀鎖
樂觀并發(fā)控制和悲觀并發(fā)控制是并發(fā)控制采用的主要方法。樂觀鎖和悲觀鎖不僅在關(guān)系數(shù)據(jù)庫(kù)里應(yīng)用,在Hibernate、Memcache等等也有相關(guān)概念。
悲觀鎖:也即悲觀并發(fā)控制,Pessimistic Concurrency Controller,縮寫PCC。悲觀鎖是指在數(shù)據(jù)處理過程,使數(shù)據(jù)處于鎖定狀態(tài),一般使用數(shù)據(jù)庫(kù)的鎖機(jī)制實(shí)現(xiàn)。
備注,在MySQL中使用悲觀鎖,必須關(guān)閉MySQL的自動(dòng)提交,set autocommit=0。MySQL默認(rèn)使用自動(dòng)提交autocommit模式,也即你執(zhí)行一個(gè)更新操作,MySQL會(huì)自動(dòng)將結(jié)果提交。
例如:使用select...for update方式將數(shù)據(jù)鎖住,也就是開啟了排他鎖
//0.開始事務(wù) begin;/begin work;/start transaction; (三者選一就可 //1.查詢出商品信息 select status from t_goods where id=1 for update; //2.根據(jù)商品信息生成訂單 insert into t_orders (id,goods_id) values (null,1); //3.修改商品status為2 update t_goods set status=2; //4.提交事務(wù) commit;/commit work;
悲觀鎖
優(yōu)點(diǎn):悲觀鎖利用數(shù)據(jù)庫(kù)中的鎖機(jī)制來實(shí)現(xiàn)數(shù)據(jù)變化的順序執(zhí)行,這是最有效的辦法
缺點(diǎn):加鎖機(jī)制會(huì)產(chǎn)生額外的開銷,增加產(chǎn)生死鎖的機(jī)會(huì)。一個(gè)事務(wù)用悲觀鎖對(duì)數(shù)據(jù)加鎖之后,其他事務(wù)將不能對(duì)加鎖的數(shù)據(jù)進(jìn)行除了查詢以外的所有操作,如果該事務(wù)執(zhí)行時(shí)間很長(zhǎng),那么其他事務(wù)將一直等待,那勢(shì)必影響我們系統(tǒng)的吞吐量。
樂觀鎖
優(yōu)點(diǎn):樂觀鎖不在數(shù)據(jù)庫(kù)上加鎖,任何事務(wù)都可以對(duì)數(shù)據(jù)進(jìn)行操作,在更新時(shí)才進(jìn)行校驗(yàn),這樣就避免了悲觀鎖造成的吞吐量下降的劣勢(shì)。
缺點(diǎn):樂觀鎖因?yàn)槭峭ㄟ^我們?nèi)藶閷?shí)現(xiàn)的,它僅僅適用于我們自己業(yè)務(wù)中,如果有外來事務(wù)插入,那么就可能發(fā)生錯(cuò)誤。
- MySQL常用存儲(chǔ)引擎的鎖機(jī)制
- BDB:支持頁(yè)級(jí)鎖和表級(jí)鎖,默認(rèn)是頁(yè)級(jí)鎖
- InnoDB:支持行級(jí)鎖和表級(jí)鎖,默認(rèn)是行級(jí)鎖
- MyISAM &Memory:這兩個(gè)存儲(chǔ)引擎都是采用表級(jí)鎖
MySQL中排它鎖和共享鎖
排它鎖(exclusive locck)
排它鎖又叫寫鎖,如果事務(wù)T對(duì)A加上排它鎖,則其它事務(wù)都不能對(duì)A加任何類型的鎖。獲準(zhǔn)排它鎖的事務(wù)既能讀數(shù)據(jù),又能寫數(shù)據(jù)。
用法:SELECT ... FOR UPDATE
共享鎖(share lock)
共享鎖又叫讀鎖,如果事務(wù)T對(duì)A加上共享鎖,則其它事務(wù)只能對(duì)A再加共享鎖,不能加其它鎖。獲準(zhǔn)共享鎖的事務(wù)只能讀數(shù)據(jù),不能寫數(shù)據(jù)。
用法:SELECT ... LOCK IN SHARE MODE;
MySQL中的行級(jí)鎖、表級(jí)鎖和頁(yè)級(jí)鎖
行級(jí)鎖:行級(jí)鎖分為共享鎖和排它鎖。行級(jí)鎖是Mysql中鎖定粒度最細(xì)的鎖。InnoDB引擎支持行級(jí)鎖和表級(jí)鎖,只有在通過索引條件檢索數(shù)據(jù)的時(shí)候,才使用行級(jí)鎖,否就使用表級(jí)鎖。行級(jí)鎖開銷大,加鎖慢,鎖定粒度最小,發(fā)生鎖沖突概率最低,并發(fā)度最高
表級(jí)鎖:表級(jí)鎖分為表共享鎖和表獨(dú)占鎖。表級(jí)鎖開銷小,加鎖快,鎖定粒度大、發(fā)生鎖沖突最高,并發(fā)度最低
頁(yè)級(jí)鎖:頁(yè)級(jí)鎖是MySQL中鎖定粒度介于行級(jí)鎖和表級(jí)鎖中間的一種鎖。表級(jí)鎖速度快,但沖突多,行級(jí)沖突少,但速度慢。所以取了折衷的頁(yè)級(jí),一次鎖定相鄰的一組記錄。BDB支持頁(yè)級(jí)鎖。
開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL開放遠(yuǎn)程連接權(quán)限的兩種方法
在我們使用mysql數(shù)據(jù)庫(kù)時(shí),有時(shí)我們的程序與數(shù)據(jù)庫(kù)不在同一機(jī)器上,這時(shí)我們需要遠(yuǎn)程訪問數(shù)據(jù)庫(kù),下面這篇文章主要給大家介紹了關(guān)于MySQL開放遠(yuǎn)程連接權(quán)限的兩種方法,需要的朋友可以參考下2022-06-06
使用LEFT?JOIN?統(tǒng)計(jì)左右存在的數(shù)據(jù)問題
最近做了一個(gè)數(shù)據(jù)模塊的統(tǒng)計(jì),統(tǒng)計(jì)企業(yè)收款、發(fā)票相關(guān)的數(shù)據(jù),開始統(tǒng)計(jì)是比較簡(jiǎn)單,后面再拆分賬套統(tǒng)計(jì)就有點(diǎn)小復(fù)雜,這篇文章主要介紹了使用LEFT?JOIN?統(tǒng)計(jì)左右存在的數(shù)據(jù),需要的朋友可以參考下2022-10-10
mysql學(xué)習(xí)筆記之?dāng)?shù)據(jù)引擎
插件式存儲(chǔ)引擎是MySQL數(shù)據(jù)庫(kù)最重要的特征之一,用戶可以根據(jù)應(yīng)用的需要尋找如何存儲(chǔ)和索引數(shù)據(jù)、是否使用事務(wù)等。MySQL默認(rèn)支持多種存儲(chǔ)引擎,以適用于不同領(lǐng)域的數(shù)據(jù)庫(kù)應(yīng)用需求,用戶可以通過選擇選擇不同的存儲(chǔ)引擎提供應(yīng)用的效率,提供靈活的存儲(chǔ)2017-02-02
MySQL腳本批量自動(dòng)插入數(shù)據(jù)及數(shù)據(jù)可按條件插入實(shí)現(xiàn)
在初始化數(shù)據(jù)庫(kù)或者導(dǎo)入一些數(shù)據(jù)時(shí),常常會(huì)用到批量的操作,本文主要介紹了MySQL腳本批量自動(dòng)插入數(shù)據(jù)及數(shù)據(jù)可按條件插入實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
mysql基礎(chǔ)架構(gòu)教程之查詢語(yǔ)句執(zhí)行的流程詳解
這篇文章主要給大家介紹了關(guān)于mysql基礎(chǔ)架構(gòu)教程之查詢語(yǔ)句執(zhí)行流程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧2018-11-11
修改MySQL所有表的編碼或修改某個(gè)字段的編碼步驟詳解
這篇文章主要給大家介紹了關(guān)于修改MySQL所有表的編碼或修改某個(gè)字段編碼的相關(guān)資料,在進(jìn)行數(shù)據(jù)庫(kù)編碼更改之前,需要先確定目標(biāo)編碼格式,常見的編碼格式有UTF-8、GBK等,需要的朋友可以參考下2023-12-12

