溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

mysql鎖機(jī)制原理及用法

發(fā)布時(shí)間:2020-05-06 15:10:07 來(lái)源:億速云 閱讀:214 作者:三月 欄目:MySQL數(shù)據(jù)庫(kù)

本文主要給大家簡(jiǎn)單講講mysql鎖機(jī)制原理及用法,相關(guān)專業(yè)術(shù)語(yǔ)大家可以上網(wǎng)查查或者找一些相關(guān)書(shū)籍補(bǔ)充一下,這里就不涉獵了,我們就直奔主題吧,希望mysql鎖機(jī)制原理及用法這篇文章可以給大家?guī)?lái)一些實(shí)際幫助。                        Mysql用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫(xiě)鎖等,都是在做操作之前先上鎖。這些鎖統(tǒng)稱為悲觀鎖(Pessimistic Lock)。

InnoDB鎖

InnoDB與MyISAM的最大不同有兩點(diǎn):

一是支持事務(wù)(TRANSACTION);

二是采用了行級(jí)鎖。行級(jí)鎖與表級(jí)鎖本來(lái)就有許多不同之處,另外,事務(wù)的引入也帶來(lái)了一些新問(wèn)題。

1、事務(wù)(Transaction)及其ACID屬性
事務(wù)是由一組SQL語(yǔ)句組成的邏輯處理單元,事務(wù)具有4屬性,通常稱為事務(wù)的ACID屬性。

1、原子性(Actomicity):事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行。

2、一致性(Consistent):在事務(wù)開(kāi)始和完成時(shí),數(shù)據(jù)都必須保持一致?tīng)顟B(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以操持完整性;事務(wù)結(jié)束時(shí),所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如B樹(shù)索引或雙向鏈表)也都必須是正確的。

3、隔離性(Isolation):數(shù)據(jù)庫(kù)系統(tǒng)提供一定的隔離機(jī)制,保證事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過(guò)程中的中間狀態(tài)對(duì)外部是不可見(jiàn)的,反之亦然。

4、持久性(Durable):事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。

mysql鎖機(jī)制原理及用法

2、并發(fā)事務(wù)帶來(lái)的問(wèn)題
相對(duì)于串行處理來(lái)說(shuō),并發(fā)事務(wù)處理能大大增加數(shù)據(jù)庫(kù)資源的利用率,提高數(shù)據(jù)庫(kù)系統(tǒng)的事務(wù)吞吐量,從而可以支持更多的用戶。但并發(fā)事務(wù)處理也會(huì)帶來(lái)一些問(wèn)題,主要包括以下幾種情況。

1、更新丟失(Lost Update):當(dāng)兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行時(shí),由于每個(gè)事務(wù)都不知道其他事務(wù)的存在,就會(huì)發(fā)生丟失更新問(wèn)題——最后的更新覆蓋了其他事務(wù)所做的更新。例如,兩個(gè)編輯人員制作了同一文檔的電子副本。每個(gè)編輯人員獨(dú)立地更改其副本,然后保存更改后的副本,這樣就覆蓋了原始文檔。最后保存其更改副本的編輯人員覆蓋另一個(gè)編輯人員所做的修改。如果在一個(gè)編輯人員完成并提交事務(wù)之前,另一個(gè)編輯人員不能訪問(wèn)同一文件,則可避免此問(wèn)題。

2、臟讀(Dirty Reads):一個(gè)事務(wù)正在對(duì)一條記錄做修改,在這個(gè)事務(wù)并提交前,這條記錄的數(shù)據(jù)就處于不一致?tīng)顟B(tài);這時(shí),另一個(gè)事務(wù)也來(lái)讀取同一條記錄,如果不加控制,第二個(gè)事務(wù)讀取了這些“臟”的數(shù)據(jù),并據(jù)此做進(jìn)一步的處理,就會(huì)產(chǎn)生未提交的數(shù)據(jù)依賴關(guān)系。這種現(xiàn)象被形象地叫做“臟讀”。

3、不可重復(fù)讀(Non-Repeatable Reads):一個(gè)事務(wù)在讀取某些數(shù)據(jù)已經(jīng)發(fā)生了改變、或某些記錄已經(jīng)被刪除了!這種現(xiàn)象叫做“不可重復(fù)讀”。

4、幻讀(Phantom Reads):一個(gè)事務(wù)按相同的查詢條件重新讀取以前檢索過(guò)的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入了滿足其查詢條件的新數(shù)據(jù),這種現(xiàn)象就稱為“幻讀”。

3、事務(wù)隔離級(jí)別
在并發(fā)事務(wù)處理帶來(lái)的問(wèn)題中,“更新丟失”通常應(yīng)該是完全避免的。但防止更新丟失,并不能單靠數(shù)據(jù)庫(kù)事務(wù)控制器來(lái)解決,需要應(yīng)用程序?qū)σ碌臄?shù)據(jù)加必要的鎖來(lái)解決,因此,防止更新丟失應(yīng)該是應(yīng)用的責(zé)任。

“臟讀”、“不可重復(fù)讀”和“幻讀”,其實(shí)都是數(shù)據(jù)庫(kù)讀一致性問(wèn)題,必須由數(shù)據(jù)庫(kù)提供一定的事務(wù)隔離機(jī)制來(lái)解決。數(shù)據(jù)庫(kù)實(shí)現(xiàn)事務(wù)隔離的方式,基本可以分為以下兩種。

1、一種是在讀取數(shù)據(jù)前,對(duì)其加鎖,阻止其他事務(wù)對(duì)數(shù)據(jù)進(jìn)行修改。

2、另一種是不用加任何鎖,通過(guò)一定機(jī)制生成一個(gè)數(shù)據(jù)請(qǐng)求時(shí)間點(diǎn)的一致性數(shù)據(jù)快照(Snapshot),并用這個(gè)快照來(lái)提供一定級(jí)別(語(yǔ)句級(jí)或事務(wù)級(jí))的一致性讀取。從用戶的角度,好像是數(shù)據(jù)庫(kù)可以提供同一數(shù)據(jù)的多個(gè)版本,因此,這種技術(shù)叫做數(shù)據(jù)多版本并發(fā)控制(MultiVersion Concurrency Control,簡(jiǎn)稱MVCC或MCC),也經(jīng)常稱為多版本數(shù)據(jù)庫(kù)。

在MVCC并發(fā)控制中,讀操作可以分成兩類:快照讀 (snapshot read)與當(dāng)前讀 (current read)??煺兆x,讀取的是記錄的可見(jiàn)版本 (有可能是歷史版本),不用加鎖。當(dāng)前讀,讀取的是記錄的最新版本,并且,當(dāng)前讀返回的記錄,都會(huì)加上鎖,保證其他事務(wù)不會(huì)再并發(fā)修改這條記錄。
在一個(gè)支持MVCC并發(fā)控制的系統(tǒng)中,哪些讀操作是快照讀?哪些操作又是當(dāng)前讀呢?以MySQL InnoDB為例:

快照讀:簡(jiǎn)單的select操作,屬于快照讀,不加鎖。(當(dāng)然,也有例外)

select * from table where ?;

當(dāng)前讀:特殊的讀操作,插入/更新/刪除操作,屬于當(dāng)前讀,需要加鎖。
下面語(yǔ)句都屬于當(dāng)前讀,讀取記錄的最新版本。并且,讀取之后,還需要保證其他并發(fā)事務(wù)不能修改當(dāng)前記錄,對(duì)讀取記錄加鎖。其中,除了第一條語(yǔ)句,對(duì)讀取記錄加S鎖 (共享鎖)外,其他的操作,都加的是X鎖 (排它鎖)。

數(shù)據(jù)庫(kù)的事務(wù)隔離越嚴(yán)格,并發(fā)副作用越小,但付出的代價(jià)也就越大,因?yàn)槭聞?wù)隔離實(shí)質(zhì)上就是使事務(wù)在一定程度上 “串行化”進(jìn)行,這顯然與“并發(fā)”是矛盾的。同時(shí),不同的應(yīng)用對(duì)讀一致性和事務(wù)隔離程度的要求也是不同的,比如許多應(yīng)用對(duì)“不可重復(fù)讀”和“幻讀”并不敏 感,可能更關(guān)心數(shù)據(jù)并發(fā)訪問(wèn)的能力。

為了解決“隔離”與“并發(fā)”的矛盾,ISO/ANSI SQL92定義了4個(gè)事務(wù)隔離級(jí)別,每個(gè)級(jí)別的隔離程度不同,允許出現(xiàn)的副作用也不同,應(yīng)用可以根據(jù)自己的業(yè)務(wù)邏輯要求,通過(guò)選擇不同的隔離級(jí)別來(lái)平衡 “隔離”與“并發(fā)”的矛盾。下表很好地概括了這4個(gè)隔離級(jí)別的特性。

mysql鎖機(jī)制原理及用法

獲取InonoD行鎖爭(zhēng)用情況

可以通過(guò)檢查InnoDB_row_lock狀態(tài)變量來(lái)分析系統(tǒng)上的行鎖的爭(zhēng)奪情況:

mysql> show status like 'innodb_row_lock%';

mysql鎖機(jī)制原理及用法

如果發(fā)現(xiàn)鎖爭(zhēng)用比較嚴(yán)重,如InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比較高,還可以通過(guò)設(shè)置InnoDB Monitors來(lái)進(jìn)一步觀察發(fā)生鎖沖突的表、數(shù)據(jù)行等,并分析鎖爭(zhēng)用的原因。

InnoDB的行鎖模式及加鎖方法

InnoDB實(shí)現(xiàn)了以下兩種類型的行鎖。

共享鎖(s):又稱讀鎖。允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上S鎖,則事務(wù)T可以讀A但不能修改A,其他事務(wù)只能再對(duì)A加S鎖,而不能加X(jué)鎖,直到T釋放A上的S鎖。這保證了其他事務(wù)可以讀A,但在T釋放A上的S鎖之前不能對(duì)A做任何修改。

排他鎖(X):又稱寫(xiě)鎖。允許獲取排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同的數(shù)據(jù)集共享讀鎖和排他寫(xiě)鎖。若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上X鎖,事務(wù)T可以讀A也可以修改A,其他事務(wù)不能再對(duì)A加任何鎖,直到T釋放A上的鎖。
對(duì)于共享鎖大家可能很好理解,就是多個(gè)事務(wù)只能讀數(shù)據(jù)不能改數(shù)據(jù)。

對(duì)于排他鎖大家的理解可能就有些差別,我當(dāng)初就犯了一個(gè)錯(cuò)誤,以為排他鎖鎖住一行數(shù)據(jù)后,其他事務(wù)就不能讀取和修改該行數(shù)據(jù),其實(shí)不是這樣的。排他鎖指的是一個(gè)事務(wù)在一行數(shù)據(jù)加上排他鎖后,其他事務(wù)不能再在其上加其他的鎖。mysql InnoDB引擎默認(rèn)的修改數(shù)據(jù)語(yǔ)句:update,delete,insert都會(huì)自動(dòng)給涉及到的數(shù)據(jù)加上排他鎖,select語(yǔ)句默認(rèn)不會(huì)加任何鎖類型,如果加排他鎖可以使用select …for update語(yǔ)句,加共享鎖可以使用select … lock in share mode語(yǔ)句。所以加過(guò)排他鎖的數(shù)據(jù)行在其他事務(wù)種是不能修改數(shù)據(jù)的,也不能通過(guò)for update和lock in share mode鎖的方式查詢數(shù)據(jù),但可以直接通過(guò)select …from…查詢數(shù)據(jù),因?yàn)槠胀ú樵儧](méi)有任何鎖機(jī)制。

另外,為了允許行鎖和表鎖共存,實(shí)現(xiàn)多粒度鎖機(jī)制,InnoDB還有兩種內(nèi)部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖。

意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行共享鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖。意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加排他鎖,事務(wù)在給一個(gè)數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。

InnoDB行鎖模式兼容性列表:

mysql鎖機(jī)制原理及用法

如果一個(gè)事務(wù)請(qǐng)求的鎖模式與當(dāng)前的鎖兼容,InnoDB就請(qǐng)求的鎖授予該事務(wù);反之,如果兩者兩者不兼容,該事務(wù)就要等待鎖釋放。
意向鎖是InnoDB自動(dòng)加的,不需用戶干預(yù)。對(duì)于UPDATE、DELETE和INSERT語(yǔ)句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X);對(duì)于普通SELECT語(yǔ)句,InnoDB不會(huì)加任何鎖。
事務(wù)可以通過(guò)以下語(yǔ)句顯式給記錄集加共享鎖或排他鎖:

1、共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

2、排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE。

用SELECT ... IN SHARE MODE獲得共享鎖,主要用在需要數(shù)據(jù)依存關(guān)系時(shí)來(lái)確認(rèn)某行記錄是否存在,并確保沒(méi)有人對(duì)這個(gè)記錄進(jìn)行UPDATE或者DELETE操作。但是如果當(dāng)前事務(wù)也需要對(duì)該記錄進(jìn)行更新操作,則很有可能造成死鎖,對(duì)于鎖定行記錄后需要進(jìn)行更新操作的應(yīng)用,應(yīng)該使用SELECT… FOR UPDATE方式獲得排他鎖。

InnoDB行鎖實(shí)現(xiàn)方式

InnoDB行鎖是通過(guò)給索引上的索引項(xiàng)加鎖來(lái)實(shí)現(xiàn)的,這一點(diǎn)MySQL與Oracle不同,后者是通過(guò)在數(shù)據(jù)塊中對(duì)相應(yīng)數(shù)據(jù)行加鎖來(lái)實(shí)現(xiàn)的。InnoDB這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過(guò)索引條件檢索數(shù)據(jù),InnoDB才使用行級(jí)鎖,否則,InnoDB將使用表鎖!
在實(shí)際應(yīng)用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導(dǎo)致大量的鎖沖突,從而影響并發(fā)性能。下面通過(guò)一些實(shí)際例子來(lái)加以說(shuō)明。

(1)在不通過(guò)索引條件查詢的時(shí)候,InnoDB確實(shí)使用的是表鎖,而不是行鎖。

mysql> create table tab_no_index(id int,name varchar(10)) engine=innodb;
Query OK, 0 rows affected (0.15 sec)
mysql> insert into tab_no_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql鎖機(jī)制原理及用法

在上面的例子中,看起來(lái)session_1只給一行加了排他鎖,但session_2在請(qǐng)求其他行的排他鎖時(shí),卻出現(xiàn)了鎖等待!原因就是在沒(méi)有索引的情況下,InnoDB只能使用表鎖。當(dāng)我們給其增加一個(gè)索引后,InnoDB就只鎖定了符合條件的行,如下例所示:
創(chuàng)建tab_with_index表,id字段有普通索引:

mysql> create table tab_with_index(id int,name varchar(10)) engine=innodb;
mysql> alter table tab_with_index add index id(id);

mysql鎖機(jī)制原理及用法

(2)由于MySQL的行鎖是針對(duì)索引加的鎖,不是針對(duì)記錄加的鎖,所以雖然是訪問(wèn)不同行的記錄,但是如果是使用相同的索引鍵,是會(huì)出現(xiàn)鎖沖突的。應(yīng)用設(shè)計(jì)的時(shí)候要注意這一點(diǎn)。
在下面的例子中,表tab_with_index的id字段有索引,name字段沒(méi)有索引:

mysql> alter table tab_with_index drop index name;
1
Query OK, 4 rows affected (0.22 sec) Records: 4 Duplicates: 0 
Warnings: 0
mysql> insert into tab_with_index  values(1,'4');
1
Query OK, 1 row affected (0.00 sec)
mysql> select * from tab_with_index where id = 1;

mysql鎖機(jī)制原理及用法

InnoDB存儲(chǔ)引擎使用相同索引鍵的阻塞例子 :

mysql鎖機(jī)制原理及用法

(3)當(dāng)表有多個(gè)索引的時(shí)候,不同的事務(wù)可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會(huì)使用行鎖來(lái)對(duì)數(shù)據(jù)加鎖。
在下面的例子中,表tab_with_index的id字段有主鍵索引,name字段有普通索引:

mysql> alter table tab_with_index add index name(name);
1Query OK, 5 rows affected (0.23 sec) Records: 5 Duplicates: 0 
Warnings: 0

InnoDB存儲(chǔ)引擎的表使用不同索引的阻塞例子 :

mysql鎖機(jī)制原理及用法

(4)即便在條件中使用了索引字段,但是否使用索引來(lái)檢索數(shù)據(jù)是由MySQL通過(guò)判斷不同執(zhí)行計(jì)劃的代價(jià)來(lái)決 定的,如果MySQL認(rèn)為全表掃描效率更高,比如對(duì)一些很小的表,它就不會(huì)使用索引,這種情況下InnoDB將使用表鎖,而不是行鎖。因此,在分析鎖沖突 時(shí),別忘了檢查SQL的執(zhí)行計(jì)劃,以確認(rèn)是否真正使用了索引。
比如,在tab_with_index表里的name字段有索引,但是name字段是varchar類型的,檢索值的數(shù)據(jù)類型與索引字段不同,雖然MySQL能夠進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,但卻不會(huì)使用索引,從而導(dǎo)致InnoDB使用表鎖。通過(guò)用explain檢查兩條SQL的執(zhí)行計(jì)劃,我們可以清楚地看到了這一點(diǎn)。

mysql> explain select * from tab_with_index where name = 1 \G
mysql> explain select * from tab_with_index where name = '1' \G

間隙鎖(Next-Key鎖)

當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請(qǐng)求共享或排他鎖時(shí),InnoDB會(huì)給符合條件的已有數(shù)據(jù)記錄的 索引項(xiàng)加鎖;對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙(GAP)”,InnoDB也會(huì)對(duì)這個(gè)“間隙”加鎖,這種鎖機(jī)制就是所謂的間隙鎖 (Next-Key鎖)。
舉例來(lái)說(shuō),假如emp表中只有101條記錄,其empid的值分別是 1,2,…,100,101,下面的SQL:

Select * from  emp where empid > 100 for update;

是一個(gè)范圍條件的檢索,InnoDB不僅會(huì)對(duì)符合條件的empid值為101的記錄加鎖,也會(huì)對(duì)empid大于101(這些記錄并不存在)的“間隙”加鎖。

InnoDB使用間隙鎖的目的,一方面是為了防止幻讀,以滿足相關(guān)隔離級(jí)別的要求,對(duì)于上面的例子,要是不使 用間隙鎖,如果其他事務(wù)插入了empid大于100的任何記錄,那么本事務(wù)如果再次執(zhí)行上述語(yǔ)句,就會(huì)發(fā)生幻讀;另外一方面,是為了滿足其恢復(fù)和復(fù)制的需 要。有關(guān)其恢復(fù)和復(fù)制對(duì)鎖機(jī)制的影響,以及不同隔離級(jí)別下InnoDB使用間隙鎖的情況,在后續(xù)的章節(jié)中會(huì)做進(jìn)一步介紹。

很顯然,在使用范圍條件檢索并鎖定記錄時(shí),InnoDB這種加鎖機(jī)制會(huì)阻塞符合條件范圍內(nèi)鍵值的并發(fā)插入,這往往會(huì)造成嚴(yán)重的鎖等待。因此,在實(shí)際應(yīng)用開(kāi)發(fā)中,尤其是并發(fā)插入比較多的應(yīng)用,我們要盡量?jī)?yōu)化業(yè)務(wù)邏輯,盡量使用相等條件來(lái)訪問(wèn)更新數(shù)據(jù),避免使用范圍條件。

還要特別說(shuō)明的是,InnoDB除了通過(guò)范圍條件加鎖時(shí)使用間隙鎖外,如果使用相等條件請(qǐng)求給一個(gè)不存在的記錄加鎖,InnoDB也會(huì)使用間隙鎖!下面這個(gè)例子假設(shè)emp表中只有101條記錄,其empid的值分別是1,2,……,100,101。
InnoDB存儲(chǔ)引擎的間隙鎖阻塞例子

mysql鎖機(jī)制原理及用法

小結(jié)

本文重點(diǎn)介紹了MySQL中MyISAM表級(jí)鎖和InnoDB行級(jí)鎖的實(shí)現(xiàn)特點(diǎn),并討論了兩種存儲(chǔ)引擎經(jīng)常遇到的鎖問(wèn)題和解決辦法。

對(duì)于MyISAM的表鎖,主要討論了以下幾點(diǎn):
(1)共享讀鎖(S)之間是兼容的,但共享讀鎖(S)與排他寫(xiě)鎖(X)之間,以及排他寫(xiě)鎖(X)之間是互斥的,也就是說(shuō)讀和寫(xiě)是串行的。
(2)在一定條件下,MyISAM允許查詢和插入并發(fā)執(zhí)行,我們可以利用這一點(diǎn)來(lái)解決應(yīng)用中對(duì)同一表查詢和插入的鎖爭(zhēng)用問(wèn)題。
(3)MyISAM默認(rèn)的鎖調(diào)度機(jī)制是寫(xiě)優(yōu)先,這并不一定適合所有應(yīng)用,用戶可以通過(guò)設(shè)置LOW_PRIORITY_UPDATES參數(shù),或在INSERT、UPDATE、DELETE語(yǔ)句中指定LOW_PRIORITY選項(xiàng)來(lái)調(diào)節(jié)讀寫(xiě)鎖的爭(zhēng)用。
(4)由于表鎖的鎖定粒度大,讀寫(xiě)之間又是串行的,因此,如果更新操作較多,MyISAM表可能會(huì)出現(xiàn)嚴(yán)重的鎖等待,可以考慮采用InnoDB表來(lái)減少鎖沖突。

對(duì)于InnoDB表,本文主要討論了以下幾項(xiàng)內(nèi)容:
(1)InnoDB的行鎖是基于索引實(shí)現(xiàn)的,如果不通過(guò)索引訪問(wèn)數(shù)據(jù),InnoDB會(huì)使用表鎖。
(2)介紹了InnoDB間隙鎖(Next-key)機(jī)制,以及InnoDB使用間隙鎖的原因。
在不同的隔離級(jí)別下,InnoDB的鎖機(jī)制和一致性讀策略不同。

在了解InnoDB鎖特性后,用戶可以通過(guò)設(shè)計(jì)和SQL調(diào)整等措施減少鎖沖突和死鎖,包括:

盡量使用較低的隔離級(jí)別; 精心設(shè)計(jì)索引,并盡量使用索引訪問(wèn)數(shù)據(jù),使加鎖更精確,從而減少鎖沖突的機(jī)會(huì);選擇合理的事務(wù)大小,小事務(wù)發(fā)生鎖沖突的幾率也更?。唤o記錄集顯式加鎖時(shí),最好一次性請(qǐng)求足夠級(jí)別的鎖。比如要修改數(shù)據(jù)的話,最好直接申請(qǐng)排他鎖,而不是先申請(qǐng)共享鎖,修改時(shí)再請(qǐng)求排他鎖,這樣容易產(chǎn)生死鎖;不同的程序訪問(wèn)一組表時(shí),應(yīng)盡量約定以相同的順序訪問(wèn)各表,對(duì)一個(gè)表而言,盡可能以固定的順序存取表中的行。這樣可以大大減少死鎖的機(jī)會(huì);盡量用相等條件訪問(wèn)數(shù)據(jù),這樣可以避免間隙鎖對(duì)并發(fā)插入的影響; 不要申請(qǐng)超過(guò)實(shí)際需要的鎖級(jí)別;除非必須,查詢時(shí)不要顯示加鎖;對(duì)于一些特定的事務(wù),可以使用表鎖來(lái)提高處理速度或減少死鎖的可能。

mysql鎖機(jī)制原理及用法就先給大家講到這里,對(duì)于其它相關(guān)問(wèn)題大家想要了解的可以持續(xù)關(guān)注我們的行業(yè)資訊。我們的板塊內(nèi)容每天都會(huì)捕捉一些行業(yè)新聞及專業(yè)知識(shí)分享給大家的。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI