欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql鎖機制之行鎖、表鎖、死鎖的實現(xiàn)

 更新時間:2022年03月16日 09:24:03   作者:這是王姑娘的微博  
本文主要介紹了Mysql鎖機制之行鎖、表鎖、死鎖的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、Mysql鎖是什么?鎖有哪些類別?

鎖定義:
    同一時間同一資源只能被一個線程訪問
    在數(shù)據(jù)庫中,除傳統(tǒng)的計算資源(如CPU、I/O等)的爭用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。如何保證數(shù)據(jù)并發(fā)訪問的一致性、有效性是所有數(shù)據(jù)庫必須解決的一個問題,鎖沖突也是影響數(shù)據(jù)庫并發(fā)訪問性能的一個重要因素。

樂觀鎖用的最多的就是數(shù)據(jù)的版本記錄來體現(xiàn) version ,其實就是一個標識。

例如:update test set a=a-1 where id=100 and a> 0; 對應的version就是a字段,并不一定非得要求有一個字段叫做version,要求的是有這個字段,同時當滿足這個條件的時候才會觸發(fā)

 鎖的分類:
從對數(shù)據(jù)操作的類型分法(讀或?qū)懀?/strong>
讀鎖(共享鎖):針對同一份數(shù)據(jù),多個讀操作可以同時進行而不會互相影響。
寫鎖(排它鎖):當前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。

從對數(shù)據(jù)操作的粒度分法
表級鎖:表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖(MyISAM引擎默認表級鎖,也只支持表級鎖)。比如說更新一張10萬表數(shù)據(jù)中的一條數(shù)據(jù),在這條update沒提交事務之前,其它事務是會被排斥掉的,粒度很大。
行級鎖:行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖(基于索引實現(xiàn)的,所以一旦某個加鎖操作沒有使用索引,那么該鎖就會退化為表鎖)
頁級鎖:頁級鎖是MySQL中鎖定粒度介于行級鎖和表級鎖中間的一種鎖,一次鎖定相鄰的一組記錄

從并發(fā)角度的分發(fā)--實際上樂觀鎖和悲觀鎖只是一種思想
悲觀鎖:對數(shù)據(jù)被外界(包括本系統(tǒng)當前的其他事務,以及來自外部系統(tǒng)的事務處理)修改持保守態(tài)度(悲觀) ,因此,在整個數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。
樂觀鎖:樂觀鎖假設認為數(shù)據(jù)一般情況下不會造成沖突,所以在數(shù)據(jù)進行提交更新的時候,才會正式對數(shù)據(jù)的沖突與否進行檢測,如果發(fā)現(xiàn)沖突了,則讓返回錯誤信息再進行業(yè)務重試

其他鎖:
間隙鎖:在條件查詢中,如:where id>100,InnoDB會給符合條件的已有數(shù)據(jù)記錄的索引項加鎖;對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,間隙的目的是為了防止幻讀
意向鎖:意向鎖分為 intention shared lock (IS) 和 intention exclusive lock (IX),意向鎖的目的就是表明有事務正在或者將要鎖住某個表中的行

二、行鎖和表鎖的區(qū)別

表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現(xiàn)簡單。最常使用的MYISAM與INNODB都支持表級鎖定。
特點:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)出鎖沖突的概率最高,并發(fā)度最低。

行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少數(shù)據(jù)庫操作的沖突。其加鎖粒度最小,但加鎖的開銷也最大。
特點:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高
使用:InnoDB行鎖是通過給索引上的索引項加鎖來實現(xiàn)的,只有通過索引條件檢索數(shù)據(jù),InnoDB才使用行級鎖,否則,InnoDB將使用表鎖

下面這個update語句,b是一般字段不是索引列的話,那么此時行級鎖將改為表級鎖。

update from test set a=100 where b='100';

現(xiàn)在舉個實際例子操作一下,看看innnodb是怎么來用行鎖的。

當前表中數(shù)據(jù):

首先開啟兩個session會話窗口,然后將mysql事務級別設置成不提交級別:

會話一窗口:

會話二窗口:

 

 其中會話2的update一直都在Running中,一直到超時結(jié)束,或者會話1提交事務后才會Running結(jié)束。

可以通過show VARIABLES like "%innodb_lock_wait_timeout%" 查詢當前mysql設置的鎖超時時間,默認是50秒。 

可以通過set innodb_lock_wait_timeout = 60; 設置鎖的超時時間。

當?shù)谝粋€會話commit之后,第二個會話的update語句才會執(zhí)行成功。這代表了innodb用了鎖。

那怎么確定是用了行鎖呢?

 

 總結(jié):會話一更新id=125的時候,給這條數(shù)據(jù)add lock了,那么在會話2中再次更新id=125的時候,這條數(shù)據(jù)是locked中的。這個lock加的是id=125這條記錄。此時除了id=125這條之外的,都是可以成功的,證明這條默認加的是行鎖。

三、InnoDB死鎖概念和死鎖案例

定義:當兩個或以上的事務相互持有和請求鎖,并形成一個循環(huán)的依賴關系,就會產(chǎn)生死鎖。多個事務同時鎖定同一個資源時,也會產(chǎn)生死鎖。在一個事務系統(tǒng)中,死鎖是確切存在并且是不能完全避免的。

解決:InnoDB會自動檢測事務死鎖,立即回滾其中某個事務,并且返回一個錯誤。它根據(jù)某種機制來選擇那個最簡單(代價最?。┑氖聞諄磉M行回滾

死鎖場景一之select for update:

產(chǎn)生場景:兩個transaction都有兩個select for update,transaction a先鎖記錄1,再鎖記錄2;而transaction b先鎖記錄2,再鎖記錄1

寫鎖:for update,讀鎖:for my share mode show engine innodb status

驗證下死鎖的場景:

 第一步更新會話一:

start TRANSACTION;
select * from wnn_test where a=199 for update;

第二步更新會話二:

start TRANSACTION;
select * from wnn_test where a=101 for update;

第三步更新會話一:

select * from wnn_test where a=101 for update;

第四步更新會話二;

select * from wnn_test where a=199 for update;

在更新到第三步和第四步的時候,已經(jīng)發(fā)生了死鎖。

來看下執(zhí)行的日志:

show engine innodb status;最后一個鎖的時間,鎖的表,引起鎖的語句。其中session1被鎖 14秒(ACTIVE 14),session 2被鎖了10秒(Active 10)

死鎖場景二之兩個update

產(chǎn)生場景:兩個transaction都有兩個update,transaction a先更新記錄1,再更新記錄2;而transaction b先更新記錄2,再更新記錄1

 產(chǎn)生日志:

 注意:仔細查看上面2個例子可以發(fā)現(xiàn)一個現(xiàn)象,當2條資源鎖住后,再執(zhí)行第三個會執(zhí)行成功,但是第四個會提示死鎖。在mysql5.7中,執(zhí)行第三個的時候就會一直在Running狀態(tài)了,本博文使用的是mysql8.0 ,其中 有這個參數(shù) innodb_deadlock_detect 可以用于控制 InnoDB 是否執(zhí)行死鎖檢測,當啟用了死鎖檢測時(默認設置),InnoDB 自動執(zhí)行事務的死鎖檢測,并且回滾一個或多個事務以解決死鎖。InnoDB 嘗試回滾更小的事務,事務的大小由它所插入、更新或者刪除的數(shù)據(jù)行數(shù)決定。

 那么這個innodb_deadlock_detect參數(shù),到底要不要啟用呢?

對于高并發(fā)的系統(tǒng),當大量線程等待同一個鎖時,死鎖檢測可能會導致性能的下降。此時,如果禁用死鎖檢測,而改為依靠參數(shù) innodb_lock_wait_timeout 執(zhí)行發(fā)生死鎖時的事務回滾可能會更加高效。
通常來說,應該啟用死鎖檢測,并且在應用程序中盡量避免產(chǎn)生死鎖,同時對死鎖進行相應的處理,例如重新開始事務。

只有在確認死鎖檢測影響了系統(tǒng)的性能,并且禁用死鎖檢測不會帶來負面影響時,可以嘗試關閉 innodb_deadlock_detect 選項。另外,如果禁用了 InnoDB 死鎖檢測,需要調(diào)整參數(shù) innodb_lock_wait_timeout 的值,以滿足實際的需求。

 四、程序開發(fā)過程中應該如何注意避免死鎖

 鎖的本質(zhì)是資源相互競爭,相互等待,往往是兩個(或以上)的Session加鎖的順序不一致

如何有效避免:

在程序中,操作多張表時,盡量以相同的順序來訪問(避免形成等待環(huán)路)

批量操作單張表數(shù)據(jù)的時候,先對數(shù)據(jù)進行排序(避免形成等待環(huán)路) A線程 id:1 ,10 ,20按順序加鎖     B線程id:20,10,1   這種的話就容易鎖。

如果可以,大事務化成小事務,甚至不開啟事務 select for update==>insert==>update = insert into update on duplicate key

盡量使用索引訪問數(shù)據(jù),避免沒有 where 條件的操作,避免鎖表 有走索引是記錄行鎖,沒走索引是表鎖

使用等值查詢而不是范圍查詢查詢數(shù)據(jù),命中記錄,避免間隙鎖對并發(fā)的影響 1,10,20 等值where id in (1,10,20) 范圍查詢 id>1 and id<20

避免在同一時間點運行多個對同一表進行讀寫的腳本,特別注意加鎖且操作數(shù)據(jù)量比較大的語句;我們經(jīng)常會有一些定時腳本,避免它們在同一時間點運行

 到此這篇關于Mysql鎖機制之行鎖、表鎖、死鎖的實現(xiàn)的文章就介紹到這了,更多相關Mysql 行鎖、表鎖、死鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL數(shù)據(jù)庫引擎介紹、區(qū)別、創(chuàng)建和性能測試的深入分析

    MySQL數(shù)據(jù)庫引擎介紹、區(qū)別、創(chuàng)建和性能測試的深入分析

    本篇文章是對MySQL數(shù)據(jù)庫引擎介紹、區(qū)別、創(chuàng)建和性能測試進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • MySQL存儲表情符號小技巧

    MySQL存儲表情符號小技巧

    這篇文章主要為大家介紹了MySQL如何存儲表情符號的小技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • MySql中 is Null段判斷無效和IFNULL()失效的解決方案

    MySql中 is Null段判斷無效和IFNULL()失效的解決方案

    這篇文章主要介紹了MySql中 is Null段判斷無效和IFNULL()失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • mysql數(shù)據(jù)庫保存路徑查找方式

    mysql數(shù)據(jù)庫保存路徑查找方式

    這篇文章主要介紹了mysql數(shù)據(jù)庫保存路徑查找方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教方法
    2023-05-05
  • MySQL group by對單字分組序和多字段分組的方法講解

    MySQL group by對單字分組序和多字段分組的方法講解

    今天小編就為大家分享一篇關于MySQL group by對單字分組序和多字段分組的方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 詳解Mysql之mysqlbackup備份與恢復實踐

    詳解Mysql之mysqlbackup備份與恢復實踐

    這篇文章主要介紹了詳解Mysql之mysqlbackup備份與恢復實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • navicat不能創(chuàng)建函數(shù)解決方法分享

    navicat不能創(chuàng)建函數(shù)解決方法分享

    這篇文章主要介紹了navicat不能創(chuàng)建函數(shù)解決方法分享,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • MySQL錯誤:Can‘t?connect?to?MySQL?server?on?localhost解決辦法(分多種情況)

    MySQL錯誤:Can‘t?connect?to?MySQL?server?on?localhost解決辦法

    這篇文章主要給大家介紹了關于MySQL錯誤:Can‘t?connect?to?MySQL?server?on?localhost的解決辦法,文中介紹的方法分多種情況,通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-05-05
  • 將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語句匯總整理

    MySQL語句匯總整理

    這篇文章主要給大家分享的是MySQL語句匯總整理,圍繞MySQL語句的相關資料對其進行整理,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你有所幫助
    2021-12-12

最新評論