最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文搞懂Mysql中的共享鎖、排他鎖、悲觀鎖、樂觀鎖及使用場景

 更新時間:2022年07月04日 10:09:42   作者:極客飛兔  
剛開始學(xué)習(xí)MySQL中鎖的時候,網(wǎng)上一查出來一堆,什么表鎖、行鎖、讀鎖、寫鎖、悲觀鎖、樂觀鎖等等等,直接整個人就懵了,下面這篇文章主要給大家介紹了關(guān)于Mysql中共享鎖、排他鎖、悲觀鎖、樂觀鎖及使用場景的相關(guān)資料,需要的朋友可以參考下

一、常見鎖類型

  • 表級鎖,鎖定整張表
  • 頁級鎖,鎖定一頁
  • 行級鎖,鎖定一行
  • 共享鎖,也叫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 行鎖是通過給索引項(xiàng)加鎖實(shí)現(xiàn)的,如果沒有索引,InnoDB 會通過隱藏的聚簇索引來對記錄加鎖。也就是說:如果不通過索引條件檢索數(shù)據(jù),那么InnoDB將對表中所有數(shù)據(jù)加鎖,實(shí)際效果跟表鎖一樣。因?yàn)闆]有了索引,找到某一條記錄就得掃描全表,要掃描全表,就得鎖定表。

四、共享鎖與排他鎖

數(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之所以要等待,是因?yàn)門2執(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í)行
  • 因?yàn)橥毁Y源上可以同時存在多個共享鎖,也被稱為,共享鎖與共享鎖兼容
  • 意味著共享鎖不阻止其他人同時讀取資源,但是阻止其他人修改資源
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'

十、意向鎖和計(jì)劃鎖

  • 計(jì)劃鎖與程序猿無關(guān),不需要了解
  • 意向鎖,Innodb特有,分為意向共享鎖和意向排他鎖
  • 意向共享鎖: 表示事務(wù)獲取共享鎖時,必須先得獲取該表的意向共享鎖
  • 意向排他鎖: 表示事務(wù)獲取排他鎖時,必須先得獲取該表的意向排他鎖
  • 我們知道要對整個表加鎖,必須保證表內(nèi)不存在任何鎖
  • 如果一行行的去檢查是否加鎖,效率必然極低,這時候可以檢測意向鎖是否被占用即可

十一、樂觀鎖和悲觀鎖

  • 樂觀鎖和悲觀鎖都是針對select而言的
  • 比如在商品搶購中,用戶購買后庫存需要減1,而很多用戶同時購買時,讀出來的庫存數(shù)量一樣,然后多個用戶同時用該庫存去減1
  • 這種做法必然會出現(xiàn)很大的漏洞,如果向在淘寶,京東出現(xiàn)這種情況,你就可以打包回家種地了
  • 這種情況如何解決呢,其實(shí)可以使用悲觀鎖進(jìn)行解決,說白了也就是排他鎖
  • 用戶進(jìn)來查庫存的時候,就加上排他鎖,等他所有操作完成后,再釋放排他鎖,讓其他人進(jìn)來
  • 不讓用戶等待,就可以使用樂觀鎖方式解決,樂觀鎖一般靠表的設(shè)計(jì)和時間戳來實(shí)現(xiàn)
  • 一般是在表中添加version或者timestamp時間戳字段
  • 這樣就會保證如果更新失敗,就表示有其他程序更新了數(shù)據(jù)庫,就可以通過重試解決
update table set num=num-1 where id=10 and version=12 

總結(jié)

到此這篇關(guān)于一文搞懂Mysql中共享鎖、排他鎖、悲觀鎖、樂觀鎖及使用場景的文章就介紹到這了,更多相關(guān)Mysql共享鎖、排他鎖、悲觀鎖、樂觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL8.0鎖等待排查的實(shí)現(xiàn)

    MySQL8.0鎖等待排查的實(shí)現(xiàn)

    MySQL8.0相較于5.7版本在鎖等待排查方面發(fā)生了顯著變化,原有的INNODB_LOCKS和INNODB_LOCK_WAITS表被移除,本篇文章將結(jié)合這些改動,介紹 MySQL 8.0 版本如何排查鎖等待問題,感興趣的可以了解一下
    2024-09-09
  • MySQL8.0設(shè)置redo緩存大小的實(shí)現(xiàn)

    MySQL8.0設(shè)置redo緩存大小的實(shí)現(xiàn)

    本文主要在MySQL 8.0.30及之后版本中使用innodb_redo_log_capacity參數(shù)在線更改redo緩存文件大小,下面就來介紹一下,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • MySQL切分函數(shù)substring()的具體使用

    MySQL切分函數(shù)substring()的具體使用

    這篇文章主要介紹了MySQL切分函數(shù)substring()的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • MySQL數(shù)據(jù)庫超時設(shè)置配置的方法實(shí)例

    MySQL數(shù)據(jù)庫超時設(shè)置配置的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫超時設(shè)置配置的相關(guān)資料,通過文中的設(shè)置方法可以很好的解決大家遇到的mysql數(shù)據(jù)庫超時問題,需要的朋友可以參考下
    2021-10-10
  • 計(jì)算機(jī)二級考試MySQL知識點(diǎn) 常用MYSQL命令

    計(jì)算機(jī)二級考試MySQL知識點(diǎn) 常用MYSQL命令

    這篇文章主要介紹了計(jì)算機(jī)二級考試MySQL知識點(diǎn),詳細(xì)介紹了常用MYSQL命令,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • mysql如何能有效防止刪庫跑路

    mysql如何能有效防止刪庫跑路

    本文主要介紹了mysql如何能有效防止刪庫跑路,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • MySQL 復(fù)制表詳解及實(shí)例代碼

    MySQL 復(fù)制表詳解及實(shí)例代碼

    這篇文章主要介紹了MySQL 復(fù)制表詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • mysql的啟動過程詳解

    mysql的啟動過程詳解

    這篇文章主要介紹了mysql的啟動過程詳解,本文用生動風(fēng)趣的文風(fēng)講解了mysql的啟動過程,絕對讓你難忘哦,需要的朋友可以參考下
    2014-08-08
  • MySQL 聲明變量及存儲過程分析

    MySQL 聲明變量及存儲過程分析

    這篇文章主要介紹了MySQL 聲明變量及存儲過程的相關(guān)內(nèi)容,小編覺得挺不錯的,這里分享給大家,需要的朋友可以參考下。
    2017-10-10
  • mysql5.7.17安裝使用圖文教程

    mysql5.7.17安裝使用圖文教程

    這篇文章主要為大家詳細(xì)介紹了MySql安裝與使用圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03

最新評論

工布江达县| 仲巴县| 孝感市| 保康县| 仪征市| 盖州市| 宜兰县| 山阴县| 重庆市| 宣城市| 日土县| 靖边县| 舞阳县| 中卫市| 芮城县| 淮滨县| 蓬安县| 沁水县| 彭水| 永宁县| 许昌县| 汝城县| 东源县| 东方市| 新龙县| 莫力| 杭州市| 新郑市| 石首市| 奉新县| 方正县| 清原| 普格县| 太康县| 临海市| 辉南县| 于田县| 闽清县| 修武县| 卢氏县| 中方县|