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

MySQL 數(shù)據(jù)庫鎖的實現(xiàn)

 更新時間:2023年03月20日 10:44:41   作者:Java-阿旭  
本文主要介紹了MySQL 數(shù)據(jù)庫鎖的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

數(shù)據(jù)庫事務(wù)-鎖機(jī)制

1.什么是鎖

鎖,其實就是一個內(nèi)存種的結(jié)構(gòu),在事務(wù)還沒有來之前是沒有鎖存在的。在事務(wù)未開始前只有一條記錄,是沒有鎖和記錄之間的關(guān)聯(lián)關(guān)系的。

鎖結(jié)構(gòu)種有很多的信息,主要的有兩個:

  • trx信息:代表這個鎖結(jié)構(gòu)是哪個事務(wù)生成的。
  • is_waiting:代表當(dāng)前事務(wù)是否在等待。

當(dāng)一條事務(wù)想要對某條記錄進(jìn)行改動時,就會生成一把鎖,在生成鎖的時候,會去檢查該條記錄有沒有被其他的鎖關(guān)聯(lián)。① 如果沒有,is_wating就是false,不需要等待,此時表示事務(wù)上鎖成功,可以進(jìn)行后續(xù)操作;② 如果有其他事務(wù)上鎖,則is_wating就是true,加鎖失敗,需要等待其他事務(wù)釋放鎖,才能后續(xù)操作該記錄。

2.鎖解決的問題

數(shù)據(jù)庫鎖主要解決并發(fā)情況下,數(shù)據(jù)隔離問題。數(shù)據(jù)庫是可以有多個客戶端連接并訪問的,這種情況就會有并發(fā)操作同一數(shù)據(jù)記錄的情況。因此數(shù)據(jù)庫出現(xiàn)了鎖機(jī)制,解決各種并發(fā)情況下出現(xiàn)的隔離問題。

3.并發(fā)訪問相同記錄的幾種情況

  • 讀-讀:多個事務(wù)同事對數(shù)據(jù)庫的同一條記錄進(jìn)行讀操作,這種情況對數(shù)據(jù)庫的記錄沒有發(fā)生變化,不會出現(xiàn)什么問題,這種情況不需要解決什么問題。
  • 寫-寫:多個事務(wù)同事對數(shù)據(jù)庫的同一條記錄進(jìn)行寫操作,這種情況會發(fā)生臟寫問題,不管那種隔離級別,都不允許這種情況的發(fā)生。所有有多個未提交的事務(wù)去操作同一條記錄時,需要讓其他事務(wù)處于阻塞排隊等待。
  • 讀-寫/寫-讀:在多并發(fā)操作同個數(shù)據(jù)記錄時,有的事務(wù)在讀,有的事務(wù)在進(jìn)行寫操作,這種情況會出現(xiàn)臟讀、不可重復(fù)讀、幻讀等情況。MySQL在repeatable read隔離級別上,已經(jīng)解決了幻讀的問題。

4.理解讀鎖和寫鎖

對于MySQL的innoDB存儲引擎來說,讀鎖/寫鎖可以作用在表上,也可以作用在行上

4.1 讀鎖

讀鎖(S)也稱共享鎖,在多個事務(wù)共同讀同一個記錄時,是可以同時讀取,互不影響,互不干擾的。
在進(jìn)行SELECT查詢操作的時候,可以使用讀鎖,使多個任務(wù)之間可以共同讀取同一條記錄。但在查詢操作時,也可以使用寫鎖,后面講寫鎖的時候再說。
如何在讀取的時候加鎖:

SELECT * FROM student LOCK IN SHARE MODE;
#或者
SELECT * FROM student FOR SHARE;#(mysql 8.0新寫法)

4.2 寫鎖

寫鎖(X)也稱排他鎖,在事務(wù)在進(jìn)行寫操作時,會上X鎖,導(dǎo)致當(dāng)前事務(wù)未完成寫操作時,其他事務(wù)的讀/寫會被阻塞。保證在同一個時間內(nèi),只有一個事務(wù)能對事務(wù)進(jìn)行讀/寫操作。

  • 在進(jìn)行讀操作的時候,也可以給記錄加X鎖,防止在讀取記錄的時候,其他事務(wù)對當(dāng)前記錄進(jìn)行更新。
  • 查詢語句加上X鎖有,其他事務(wù)不能再給該記錄加S鎖或X鎖。其他事務(wù)會阻塞,知道當(dāng)前事務(wù)釋放X鎖。
  • 給查詢操作加X鎖:
SELECT * FROM student FOR UPDATE;

進(jìn)行寫操作時,會自動給該條記錄加X鎖。寫記錄:INSERT\DELETE\UPDATE 4.3 讀鎖和寫鎖的兼容情況

讀寫

5.表鎖

表鎖是指給所操作的整張表進(jìn)行加鎖,相對行鎖,對表加鎖的顆粒度比較大,因此它的開銷也比較小。由于是對整張數(shù)據(jù)表進(jìn)行加鎖,因此可以避免死鎖的出現(xiàn)。即使這樣,是對整張表進(jìn)行加鎖,就會導(dǎo)致大量的事務(wù)無法繼續(xù)操作表,所有表鎖的性能是較差的。
在MySQL中,InnoDB提供了表鎖行鎖由于表鎖的性能比較差,一般我們都很少用到表鎖。只有特殊場景下會用到表鎖,比如:數(shù)據(jù)崩潰恢復(fù)。

5.1 表級的讀/寫鎖

  • 對表加S鎖:MySQL的InnoDB對整個表加S鎖。
  • 對表加X鎖:MySQL的InnoDB對整個表加X鎖。

查看有那些表被加鎖:

SHOW OPEN TABLES;
#或者
SHOW OPEN TABLES WHERE In_use >0;

手動給表加鎖:

LOCK TABLES student READ;#給student表加S鎖
LOCK TABLES stdent WRITE;#給student表加X鎖

釋放鎖:

UNLOCK TABLES;

小結(jié)

5.2 意向鎖

MySQL的InnoDB存儲引擎中,支持表鎖和行鎖同時存在,而意向鎖就是表鎖的一種。

意向鎖是為了協(xié)調(diào)表鎖行鎖同時共存而存在的。意向鎖是一中不于行鎖沖突的表級鎖。意向鎖用戶是無法手動添加的,它是InnoDB存儲引擎自動給加的。當(dāng)在給某個行添加S鎖或X鎖時,需要先獲取當(dāng)前行所在表的意向鎖。

意向鎖分為兩種:

  • 意向共享鎖(IS):事務(wù)有意向?qū)Ρ碇械哪承屑庸蚕礞i(S鎖)。當(dāng)給某一行記錄加了共享鎖(S)后,數(shù)據(jù)庫就會給當(dāng)前的數(shù)據(jù)表或數(shù)據(jù)頁加上意向共享鎖,當(dāng)想給當(dāng)前表加入一個排他鎖(X)時,就會檢測到意向共享鎖,就會被排斥阻塞,不能加鎖。但是加表的共享鎖時,是可以的。
  • 意向排他鎖(IX):事務(wù)有意向?qū)Ρ碇械哪承屑优潘i(X鎖)。當(dāng)給某一行記錄加了排他鎖(X)后,數(shù)據(jù)庫就會給當(dāng)前的數(shù)據(jù)表或數(shù)據(jù)頁加上意向排他鎖,當(dāng)想給當(dāng)前表加入一個排他鎖(X)或者意向鎖(S)時,就會檢測到意向排他鎖,就會被排斥阻塞,不能加鎖。

理解意向鎖的意義:當(dāng)沒有意向鎖的時候,當(dāng)事務(wù)想要給表加表鎖的時候,需要去檢測每行記錄是否加有鎖,這樣每條檢測的效率非常的低。意向鎖的出現(xiàn),很好的解決這種情況。有意向鎖后,事務(wù)要表添加鎖,只要檢查當(dāng)前表是否有意向鎖就可以了。

總結(jié):意向鎖之間是互相兼容的和讀寫鎖不兼容:

6.行鎖

行鎖就是給表中的某條記錄上把鎖,將該條記錄鎖住。行鎖是在InnoDB存儲引擎層實現(xiàn)的,這是InnoDB與MyISAM最大的區(qū)別之一。行鎖是粒度小的,發(fā)生鎖沖突的概率很小,因此會實現(xiàn)高并發(fā)的效果,但是因粒度較小,加鎖較慢,會出現(xiàn)死鎖的情況

6.1 記錄鎖

記錄鎖就是一把行鎖,顧名思義,給某條記錄上鎖。

  • 共享記錄鎖(S):當(dāng)一個事務(wù)得到了某個事務(wù)的共享鎖后,其他事務(wù)還能繼續(xù)獲取該記錄的共享鎖,但是不能獲取該記錄的排他鎖。
  • 排他記錄鎖(X):當(dāng)一個事務(wù)得到了某個事務(wù)的排他鎖后,其他事務(wù)不能獲取該記錄的共享鎖和排他鎖。

6.2 間隙鎖

間隙鎖是在某個記錄前的間隙加入一個鎖,這樣就使該記錄前面的間隙是不能添加數(shù)據(jù)的。這種間隙鎖有效的防止了幻讀的出現(xiàn)。間隙鎖的出現(xiàn),也是為了解決幻讀而提出來的。
不管是共享鎖還是排他鎖,起到的作用是一樣的,
舉例:

select * from student where id=11 for update;

此時id為18加了間隙鎖

這種會出現(xiàn)一個問題,因為間隙鎖只會鎖住行前面的間隙,那么,如果此時給id為25后面的間隙插入數(shù)據(jù),就會有問題,此時,數(shù)據(jù)庫做了兩個提供了兩個偽記錄: Infimum記錄,表示該頁面中最小的記錄。 Supremun記錄,表示該頁面中最大的記錄。
加入如下,就可以阻止其他事務(wù)加入(25,+∞)的數(shù)據(jù)了。

select * from student where id > 20 lock in share mode;

間隙鎖的出現(xiàn),會發(fā)生死鎖,如下:

當(dāng)記錄中存在間隙鎖時,有其他事務(wù)想在這個間隙插入數(shù)據(jù),由于鎖的存在,會阻止插入,讓事務(wù)進(jìn)行等待,知道釋放間隙鎖。此時內(nèi)存中會生成一個插入意向鎖,這個意向鎖是一種間隙鎖,并不是表鎖中的意向鎖。這種插入意向鎖可以有多個,一個間隙中有多個插入意向鎖并不沖突,插入意向鎖之間不會有排斥。

6.3 臨界鎖

臨界鎖是用來補(bǔ)充上面說的間隙鎖,因為間隙鎖只是鎖住了記錄前面的間隙,但是并不包含自己,因此臨界鎖就出現(xiàn)了,臨界鎖就是記錄鎖和間隙鎖的組合體。

select * from student where id <=18 and id > 10 for update;

7.悲觀鎖和樂觀鎖

悲觀鎖、樂觀鎖其實并不是一種鎖,而是一中并發(fā)下鎖的一種設(shè)計思想

7.1 悲觀鎖

  • 悲觀鎖,就是很悲觀,對數(shù)據(jù)被其他事務(wù)操作的時候,保持悲觀態(tài)度??偸钦J(rèn)為數(shù)據(jù)會被其他事務(wù)修改,所以每次操作數(shù)據(jù)的時候,都會被數(shù)據(jù)上鎖,使別他事務(wù)操作數(shù)據(jù)的時候處于阻塞狀態(tài),知道釋放鎖,保證數(shù)據(jù)具有排他性。
  • 行鎖、表鎖、讀鎖、寫鎖就是悲觀鎖的體現(xiàn),每次在操作數(shù)據(jù)的時候,都會加鎖,使其他數(shù)據(jù)在訪問的時候被阻塞掛起,直到釋放鎖。
  • 其實悲觀鎖的使用場景并不是很多,因為它在每次操作的時候,都會給數(shù)據(jù)上鎖,這樣會在事務(wù)比較長的時候,性能會比較差。
  • 悲觀鎖的適用場景是寫操作多的情況下,因為寫具有排他性,在寫操作的時候,阻止其他事務(wù)對數(shù)據(jù)的讀或?qū)懙牟僮?,這樣很大的避免了讀-寫/寫-讀的沖突,進(jìn)而避免了臟讀、不可重復(fù)讀、幻讀的問題。

7.2 樂觀鎖

樂觀鎖,就是對數(shù)據(jù)的操作持有樂觀的態(tài)度,任務(wù)每次操作數(shù)據(jù)時,都不會有其他的事務(wù)對數(shù)據(jù)進(jìn)行修改操作。但是在每次一修改數(shù)據(jù)的時候,都會判斷在此期間數(shù)據(jù)是否被其他事務(wù)修改過。

樂觀鎖是在操作數(shù)據(jù)的時候,通過程序來進(jìn)行控制的,比如:使用版本號,或者時間戳來進(jìn)行比對。

  • 版本號的樂觀鎖: 在數(shù)據(jù)表中,添加一個字段’version’,這個字段使用來記錄每次數(shù)據(jù)跟新后的數(shù)據(jù)版本。在進(jìn)行數(shù)據(jù)的更新操作時,會先拿到’version’字段的值,更新數(shù)據(jù)的時候,會拿之前的version的值和現(xiàn)在數(shù)據(jù)庫里面的‘version’進(jìn)行比較,如果兩個‘version’的值是一樣的,說明在此期間數(shù)據(jù)沒有被修改過,可以進(jìn)行更新操作。反過來,如果兩個‘version’的值不一樣,說明此期間有其他事務(wù)修改過這條記錄,則更新失敗。
  • 在更新數(shù)據(jù)的時候,會使’version’的值加1。
`UPDATE student SET name= '李四' ,version=version+1 WHERE version=version` 

樂觀鎖的適用場景讀多寫少的場景,由程序?qū)崿F(xiàn),不會出現(xiàn)死鎖問題。

7.3 總結(jié)

到此這篇關(guān)于MySQL 數(shù)據(jù)庫鎖的實現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL 數(shù)據(jù)庫鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql8.0主從復(fù)制搭建與配置方案

    mysql8.0主從復(fù)制搭建與配置方案

    MySQL主從復(fù)制是一個異步的復(fù)制過程,就是有兩個數(shù)據(jù)庫服務(wù)器,一個是主(master)數(shù)據(jù)庫服務(wù)器,另一個是從(slave)數(shù)據(jù)庫服務(wù)器。
    2022-09-09
  • MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的方案

    MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的方案

    這篇文章主要介紹了MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的情況,文中通過圖文結(jié)合的方式給大家講解的非常詳細(xì),對大家解決問題有一定的幫助,需要的朋友可以參考下
    2024-11-11
  • MySQL OOM(內(nèi)存溢出)的解決思路

    MySQL OOM(內(nèi)存溢出)的解決思路

    這篇文章主要介紹了MySQL OOM(內(nèi)存溢出)的解決思路,文中講解非常細(xì)致,幫助大家在學(xué)習(xí)工作中解決內(nèi)存溢出的問題,感興趣的朋友可以了解下
    2020-08-08
  • 一文帶你了解MySQL中觸發(fā)器的操作

    一文帶你了解MySQL中觸發(fā)器的操作

    觸發(fā)器,就是一種特殊的存儲過程。觸發(fā)器和存儲過程一樣是一個能夠完成特定功能、存儲在數(shù)據(jù)庫服務(wù)器上的SQL片段。本文將通過簡單的實力介紹一下觸發(fā)器的操作,需要的可以參考一下
    2023-02-02
  • Centos 6.5 下安裝mysql 5.6.21的方法

    Centos 6.5 下安裝mysql 5.6.21的方法

    本文給大家?guī)鞢entos 6.5 下安裝mysql 5.6.21的方法,操作方法比較簡單,介紹的非常詳細(xì),感興趣的朋友可以參考下操作步驟
    2016-09-09
  • linux CentOS 7.4下 mysql5.7.20 密碼改回來的處理方法

    linux CentOS 7.4下 mysql5.7.20 密碼改回來的處理方法

    這篇文章主要介紹了linux CentOS 7.4下 mysql5.7.20 密碼改回來的處理方法,需要的朋友可以參考下
    2018-11-11
  • MySql允許遠(yuǎn)程連接如何實現(xiàn)該功能

    MySql允許遠(yuǎn)程連接如何實現(xiàn)該功能

    這篇文章主要介紹了 MySql允許遠(yuǎn)程連接如何實現(xiàn)該功能的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • MySQL實戰(zhàn)教程之Join語句執(zhí)行流程

    MySQL實戰(zhàn)教程之Join語句執(zhí)行流程

    這篇文章主要介紹了MySQL Join語句執(zhí)行流程,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 將MySQL help contents的內(nèi)容有層次的輸出方法推薦

    將MySQL help contents的內(nèi)容有層次的輸出方法推薦

    如何將MySQL help contents的內(nèi)容有層次的輸出呢?下面小編就為大家?guī)硪黄獙ySQL help contents的內(nèi)容有層次的輸出方法推薦。小編覺得挺不錯的,現(xiàn)在分享給大家,給大家一個參考。一起跟隨小編過來看看吧
    2016-03-03
  • MySQL數(shù)據(jù)庫的事務(wù)和索引詳解

    MySQL數(shù)據(jù)庫的事務(wù)和索引詳解

    這篇文章主要介紹了MySql 索引和事務(wù),總結(jié)分析了mysql數(shù)據(jù)庫中關(guān)于索引和事務(wù)的概念、原理、知識點(diǎn)及相關(guān)注意事項,需要的朋友可以參考下
    2021-10-10

最新評論

什邡市| 鄂尔多斯市| 固原市| 定西市| 道真| 区。| 高邑县| 义马市| 锦州市| 青铜峡市| 安陆市| 闵行区| 尼木县| 米泉市| 监利县| 疏附县| 温州市| 凤台县| 奉化市| 张家港市| 池州市| 察雅县| 惠水县| 琼海市| 金寨县| 西青区| 从江县| 新昌县| 崇义县| 武穴市| 玛沁县| 轮台县| 丘北县| 徐汇区| 丽江市| 东明县| 临安市| 团风县| 伊通| 蒙自县| 福建省|