久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Mysql中鎖的使用場景是什么

168次閱讀
沒有評論

共計 3340 個字符,預(yù)計需要花費(fèi) 9 分鐘才能閱讀完成。

這篇文章主要講解了“Mysql 中鎖的使用場景是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Mysql 中鎖的使用場景是什么”吧!

一、常見鎖類型

表級鎖,鎖定整張表

頁級鎖,鎖定一頁

行級鎖,鎖定一行

共享鎖,也叫 S 鎖,在 MyISAM 中也叫讀鎖

排他鎖,也叫 X 鎖,在 MyISAM 中也叫寫鎖

悲觀鎖,抽象性質(zhì),其實(shí)不真實(shí)存在

樂觀鎖,抽象性質(zhì),其實(shí)不真實(shí)存在

常見鎖類型二、Mysql 引擎介紹

其實(shí) mysql 中的引擎有很多種類,其中 InnoDB 和 MyISAM 引擎最常用

在 mysql5.5 版本前默認(rèn)使用 MyISAM 引擎,之后使用 InnoDB 引擎

查看數(shù)據(jù)庫引擎命令如下

show variables like  %storage_engine%

三、常用引擎間的區(qū)別

MyISAM 操作數(shù)據(jù)都是使用的表鎖,你更新一條記錄就要鎖整個表,導(dǎo)致性能較低,并發(fā)不高。當(dāng)然同時它也不會存在死鎖問題。

而 InnoDB 與 MyISAM 的最大不同有兩點(diǎn):一是 InnoDB 支持事務(wù);二是 InnoDB 采用了行級鎖。

在 Mysql 中,行級鎖并不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條 sql 語句操作了主鍵索引,Mysql 就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL 會先鎖定該非主鍵索引,再鎖定相關(guān)的主鍵索引。

InnoDB 行鎖是通過給索引項加鎖實(shí)現(xiàn)的,如果沒有索引,InnoDB 會通過隱藏的聚簇索引來對記錄加鎖。也就是說:如果不通過索引條件檢索數(shù)據(jù),那么 InnoDB 將對表中所有數(shù)據(jù)加鎖,實(shí)際效果跟表鎖一樣。因為沒有了索引,找到某一條記錄就得掃描全表,要掃描全表,就得鎖定表。

四、共享鎖與排他鎖

數(shù)據(jù)庫的增刪改操作默認(rèn)都會加排他鎖,而查詢不會加任何鎖。

共享鎖:對某一資源加共享鎖,自身可以讀該資源,其他人也可以讀該資源(也可以再繼續(xù)加共享鎖,即 共享鎖可多個共存),但無法修改。要想修改就必須等所有共享鎖都釋放完之后。

排他鎖:對某一資源加排他鎖,自身可以進(jìn)行增刪改查,其他人無法進(jìn)行任何操作。

// 共享鎖
select * from  表名  lock in share mode
// 排他鎖
select * from  表名  for update

五、排他鎖的實(shí)際應(yīng)用

這里我們以兩個操作數(shù)據(jù)庫的請求為例,假設(shè)這兩個請求分別為 T1 和 T2

假設(shè) T1 為查詢請求,而 T2 為更新數(shù)據(jù)請求,在 T1 查詢很長時間的時候,還沒有返回結(jié)果,但是這時候 T2 過來請求更新了

這個流程應(yīng)該是: T1 運(yùn)行加共享鎖、T2 運(yùn)行、發(fā)現(xiàn) T1 未完成等待其完成、T1 完成、T2 開始執(zhí)行

T2 之所以要等待,是因為 T2 執(zhí)行更新的時候需要給表加排他鎖,但是數(shù)據(jù)庫規(guī)定,不能在同一資源上同時共存這兩種鎖,所以 T2 必須等 T1 執(zhí)行完,釋放鎖后,才可以正常操作

T1: select * from  表名  lock in share mode // 假設(shè)還未返回結(jié)果
T2: update  表名  set name= autofelix

六、共享鎖的實(shí)際應(yīng)用

如果 T1 和 T2 都是執(zhí)行的查詢,也就是都加共享鎖

這時候就不用等待,可以立馬執(zhí)行

因為同一資源上可以同時存在多個共享鎖,也被稱為,共享鎖與共享鎖兼容

意味著共享鎖不阻止其他人同時讀取資源,但是阻止其他人修改資源

T1: select * from table lock in share mode
T2: select * from table lock in share mode

七、死鎖的發(fā)生

假設(shè) T1 和 T2 都同時執(zhí)行 2 個資源操作,分別是查詢和更新數(shù)據(jù)

假設(shè) T1 和 T2 同時達(dá)到 select,T1 對表加共享鎖,而 T2 也加上了共享鎖

當(dāng) T1 的 select 執(zhí)行完畢,準(zhǔn)備執(zhí)行 update 時

根據(jù)鎖機(jī)制,T1 的共享鎖必須升級到排他鎖才可以執(zhí)行接下來的 update 操作

在升級排他鎖之前,必須等 T2 的共享鎖釋放,同理,T2 也在等 T1 的共享鎖釋放

于是都在等待對方的鎖釋放,導(dǎo)致程序卡死,這種情況就是死鎖

T1:  開啟事務(wù), 執(zhí)行查詢更新兩個操作
 select * from table lock in share mode
 update table set column1= hello 
T2:  開啟事務(wù), 執(zhí)行查詢更新兩個操作
 select * from table lock in share mode
 update table set column1= world

八、另一種發(fā)生死鎖的情景

當(dāng) T1 和 T2 都是只執(zhí)行更新語句的時候

如下程序所示,這種語句非常的常見,很多人覺得他會產(chǎn)生死鎖,其實(shí)要看情況

如果 id 是主鍵,由于主鍵機(jī)制,并不需要全表掃描,直接可以更新當(dāng)前數(shù)據(jù),所以不會產(chǎn)生死鎖

如果 id 是普通字段,那么當(dāng) T1 加上排他鎖之后,T2 為了找到 id=20 條數(shù)據(jù),必須進(jìn)行全表掃描,當(dāng)他掃到第 10 條的時候,發(fā)現(xiàn)這里有排他鎖,導(dǎo)致全表掃描進(jìn)行不下去,就會導(dǎo)致等待

T1: begin
 update table set content= hello  where id=10
T2: begin
 update table set content= world  where id=20

九、死鎖的解決方式

就是讓 T1 和 T2 順序執(zhí)行,比如 T1 在執(zhí)行完 select 后,立馬給自身加上排他鎖,這樣 T2 不得不等待 T1 執(zhí)行完才能繼續(xù)

但是如果有很多請求過來的話,都必須等待,這對用戶特別的不友好

所以,某些數(shù)據(jù)庫引入了另一種方式,叫做更新鎖,這里 mysql 除外,不存在更新鎖

更新鎖其實(shí)就是排他鎖的另一種實(shí)現(xiàn),只是他允許其他人讀的同時加共享鎖,但是不允許其他操作,除非釋放了更新鎖

流程大概如此: T1 執(zhí)行完 select 加上更新鎖,T2 執(zhí)行查詢完,準(zhǔn)備加更新鎖,發(fā)現(xiàn)已經(jīng)有了,就等待,其他請求過來,如果查詢是不受影響的,但是更新才等待

這相比上面的查詢也要等待增加了效率

T1: begin
 select * from table for update
 update table set content= hello 
T2: begin
 select * from table for update
 update table set content= world
T1: begin
 select * from table [加更新鎖操作]
 update table set content= hello 
T2: begin
 select * from table [加更新鎖操作]
 update table set content= world

十、意向鎖和計劃鎖

計劃鎖與程序猿無關(guān),不需要了解

意向鎖,Innodb 特有,分為意向共享鎖和意向排他鎖

意向共享鎖: 表示事務(wù)獲取共享鎖時,必須先得獲取該表的意向共享鎖

意向排他鎖: 表示事務(wù)獲取排他鎖時,必須先得獲取該表的意向排他鎖

我們知道要對整個表加鎖,必須保證表內(nèi)不存在任何鎖

如果一行行的去檢查是否加鎖,效率必然極低,這時候可以檢測意向鎖是否被占用即可

十一、樂觀鎖和悲觀鎖

樂觀鎖和悲觀鎖都是針對 select 而言的

比如在商品搶購中,用戶購買后庫存需要減 1,而很多用戶同時購買時,讀出來的庫存數(shù)量一樣,然后多個用戶同時用該庫存去減 1

這種做法必然會出現(xiàn)很大的漏洞,如果向在淘寶,京東出現(xiàn)這種情況,你就可以打包回家種地了

這種情況如何解決呢,其實(shí)可以使用悲觀鎖進(jìn)行解決,說白了也就是排他鎖

用戶進(jìn)來查庫存的時候,就加上排他鎖,等他所有操作完成后,再釋放排他鎖,讓其他人進(jìn)來

不讓用戶等待,就可以使用樂觀鎖方式解決,樂觀鎖一般靠表的設(shè)計和時間戳來實(shí)現(xiàn)

一般是在表中添加 version 或者 timestamp 時間戳字段

這樣就會保證如果更新失敗,就表示有其他程序更新了數(shù)據(jù)庫,就可以通過重試解決

update table set num=num-1 where id=10 and version=12

感謝各位的閱讀,以上就是“Mysql 中鎖的使用場景是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對 Mysql 中鎖的使用場景是什么這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-13發(fā)表,共計3340字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 抚宁县| 鹤山市| 东山县| 湘潭市| 牟定县| 大丰市| 海门市| 农安县| 锡林郭勒盟| 嘉峪关市| 屏边| 南汇区| 安福县| 潞西市| 昌邑市| 蓝山县| 梁平县| 建水县| 横山县| 个旧市| 达日县| 安龙县| 弥勒县| 井陉县| 安岳县| 泗水县| 喀喇沁旗| 公主岭市| 杨浦区| 高邑县| 金山区| 齐河县| 永平县| 饶阳县| 神木县| 盱眙县| 万宁市| 巴林左旗| 邻水| 土默特左旗| 松潘县|