亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

1.什么是鎖

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

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

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

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

2.鎖解決的問(wèn)題

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

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

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

4.理解讀鎖和寫(xiě)鎖

對(duì)于MySQL的innoDB存儲(chǔ)引擎來(lái)說(shuō),讀鎖/寫(xiě)鎖可以作用在表上,也可以作用在行上

4.1 讀鎖

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

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

4.2 寫(xiě)鎖

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

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

進(jìn)行寫(xiě)操作時(shí),會(huì)自動(dòng)給該條記錄加X(jué)鎖。寫(xiě)記錄:INSERT\DELETE\UPDATE 4.3 讀鎖和寫(xiě)鎖的兼容情況

讀寫(xiě)

5.表鎖

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

5.1 表級(jí)的讀/寫(xiě)鎖

  • 對(duì)表加S鎖:MySQL的InnoDB對(duì)整個(gè)表加S鎖。
  • 對(duì)表加X(jué)鎖:MySQL的InnoDB對(duì)整個(gè)表加X(jué)鎖。

查看有那些表被加鎖:

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

手動(dòng)給表加鎖:

LOCK TABLES student READ;#給student表加S鎖
LOCK TABLES stdent WRITE;#給student表加X(jué)鎖

釋放鎖:

UNLOCK TABLES;

小結(jié)

5.2 意向鎖

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

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

意向鎖分為兩種:

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

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

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

6.行鎖

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

6.1 記錄鎖

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

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

6.2 間隙鎖

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

select * from student where id=11 for update;

此時(shí)id為18加了間隙鎖

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

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

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

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

6.3 臨界鎖

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

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

7.悲觀鎖和樂(lè)觀鎖

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

7.1 悲觀鎖

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

7.2 樂(lè)觀鎖

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

樂(lè)觀鎖是在操作數(shù)據(jù)的時(shí)候,通過(guò)程序來(lái)進(jìn)行控制的,比如:使用版本號(hào),或者時(shí)間戳來(lái)進(jìn)行比對(duì)。

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

樂(lè)觀鎖的適用場(chǎng)景讀多寫(xiě)少的場(chǎng)景,由程序?qū)崿F(xiàn),不會(huì)出現(xiàn)死鎖問(wèn)題。

7.3 總結(jié)

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

相關(guān)文章

  • MySql無(wú)法連接本地地址localhost問(wèn)題

    MySql無(wú)法連接本地地址localhost問(wèn)題

    這篇文章主要介紹了MySql無(wú)法連接本地地址localhost問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • MySQL表的增刪查改及聚合函數(shù)/group?by子句的使用方法舉例

    MySQL表的增刪查改及聚合函數(shù)/group?by子句的使用方法舉例

    這篇文章主要給大家介紹了關(guān)于MySQL表的增刪查改及聚合函數(shù)/group?by子句的使用方法,在MySQL中可以使用聚合函數(shù)與GROUP BY語(yǔ)句可以對(duì)數(shù)據(jù)進(jìn)行分組并進(jìn)行聚合計(jì)算,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • mysql占用CPU超過(guò)100%的詳細(xì)解決過(guò)程

    mysql占用CPU超過(guò)100%的詳細(xì)解決過(guò)程

    前段時(shí)間我的一個(gè)網(wǎng)站經(jīng)常打不開(kāi),通過(guò)檢查發(fā)現(xiàn)服務(wù)器cpu占用超過(guò)100%,通過(guò)top命令發(fā)現(xiàn)是mysql占用cpu特別高導(dǎo)致的,下面這篇文章主要給大家介紹了關(guān)于mysql占用CPU超過(guò)100%的詳細(xì)解決過(guò)程,需要的朋友可以參考下
    2023-10-10
  • 線上MySQL的自增id用盡怎么辦

    線上MySQL的自增id用盡怎么辦

    MySQL的自增id都定義了初始值,然后不斷加步長(zhǎng)。雖然自然數(shù)沒(méi)有上限,但定義了表示這個(gè)數(shù)的字節(jié)長(zhǎng)度,那自增id用完,會(huì)怎么樣?本文就來(lái)介紹一下
    2021-08-08
  • Mysql?8.0?綠色版安裝教程詳解

    Mysql?8.0?綠色版安裝教程詳解

    這篇文章主要為大家詳細(xì)介紹了Mysql?8.0?綠色版安裝教程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Ubuntu Server下MySql數(shù)據(jù)庫(kù)備份腳本代碼

    Ubuntu Server下MySql數(shù)據(jù)庫(kù)備份腳本代碼

    為了mysql數(shù)據(jù)庫(kù)的安全,我們需要定時(shí)備份mysql數(shù)據(jù)庫(kù),這里提供下腳本代碼,需要的朋友可以參考下
    2013-06-06
  • Mysql5.7如何修改root密碼

    Mysql5.7如何修改root密碼

    mysql修改管理員root的密碼是個(gè)很常見(jiàn)的問(wèn)題了,網(wǎng)上也有很多的教程,然而新版的MYSQL5.7卻能使用之前的教程,小編經(jīng)過(guò)一番摸索,才找到了修改辦法,這里分享給大家。
    2016-01-01
  • 關(guān)于InnoDB索引的底層實(shí)現(xiàn)和實(shí)際效果

    關(guān)于InnoDB索引的底層實(shí)現(xiàn)和實(shí)際效果

    這篇文章主要介紹了關(guān)于InnoDB索引的底層實(shí)現(xiàn)和實(shí)際效果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Windows下MySQL8.0.18安裝教程(圖解)

    Windows下MySQL8.0.18安裝教程(圖解)

    這篇文章主要介紹了Windows下MySQL8.0.18安裝教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Centos 7下使用RPM包安裝MySQL 5.7.9教程

    Centos 7下使用RPM包安裝MySQL 5.7.9教程

    這篇文章主要為大家詳細(xì)介紹了Centos 7下使用RPM包安裝MySQL 5.7.9的教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評(píng)論