天天看點

Mariadb之顯式使用表鎖和行級鎖

Mariadb之顯式使用表鎖和行級鎖

首先我們來看看mariadb的鎖定概念,所謂鎖就是當一個程序或事務在操作某一資源時,為了防止其他使用者或者程序或事務對其進行資源操作,導緻資源搶占而發生沖突,通常在A程序操作該資源時,會對該資源進行加鎖,實作多程序或多使用者操作同一資源時,不會發生沖突;通常情況鎖的類型分讀鎖和寫鎖,所謂讀鎖就是共享鎖,它可以實作多個讀操作共享;而寫鎖就是排它鎖,獨占鎖,一旦加了寫鎖,其他使用者的讀寫操作将被阻塞,直到該寫鎖被釋放或者因逾時而被釋放,在其他使用者進行的讀寫操作,此時就會被執行;

  首先我們來看看mariadb的鎖的概念,所謂鎖就是當一個程序或事務在操作某一資源時,為了防止其他使用者或者程序或事務對其進行資源操作,導緻資源搶占而發生沖突,通常在A程序操作該資源時,會對該資源進行加鎖,實作多程序或多使用者操作同一資源時,不會發生沖突;通常情況鎖的類型分讀鎖和寫鎖,所謂讀鎖就是共享鎖,它可以實作多個讀操作共享;而寫鎖就是排它鎖,獨占鎖,一旦加了寫鎖,其他使用者的讀寫操作将被阻塞,直到該寫鎖被釋放或者因逾時而被釋放,在其他使用者進行的讀寫操作,此時就會被執行;對于鎖定範圍來講,它又可以分為,表鎖和行鎖,從字面意思就可以了解到,表鎖就是針對整張表所施加的鎖,而這種鎖定力度相當粗糙,并發相對就比較低,但是維持鎖狀态鎖消耗的成本資源就較小;對于行鎖來說,它針對的範圍就是行級别所施加的鎖,這種鎖的粒度就相對要精細,同時并發相對較高,但是維護鎖狀态消耗的成本資源就相對要大;對于mysql來講又鎖分為存儲引擎級别的鎖和mysql server級别的鎖,存儲引擎級别的鎖指的是對于何時施加鎖或者釋放鎖由存儲引擎自行決定;mysql server級别鎖指的是使用者使用指令可自行決定施加鎖或釋放鎖;簡單講就是允許使用者顯式請求加鎖或釋放鎖;顯式鎖就是使用者手動用指令施加的鎖,隐式鎖指的是由存儲引擎根據需要自行施加的鎖;對于innodb存儲引擎來講,它支援事務,行級鎖;而早期的MyISAM存儲引擎它不支援事務,對鎖的粒度是表級鎖,不支援行級鎖;

  顯示鎖的使用

  1)LOCK TABLES

    指令使用文法:

    LOCK TABLES  tbl_name  read|write, tbl_name read|write, ...

  示例:

Mariadb之顯式使用表鎖和行級鎖

  提示:以上語句表示對test_tb這張表施加讀鎖操作,這意味着其他使用者或程序都不能對該表進行寫的操作,隻能讀,因為讀鎖是共享鎖;

  測試:對test_tb表進行寫操作,看看是否能夠寫進去?

Mariadb之顯式使用表鎖和行級鎖

  提示:從上面的提示,它告訴我們test_tb這張表施加了讀鎖,不允許更新;這說明施加讀鎖,對于寫的操作就不能進行;

  測試:對test_tb表進行讀操作,看看是否能夠進行呢?

Mariadb之顯式使用表鎖和行級鎖

  提示:可以看到加了讀鎖的表,對于讀操作上可以繼續進行的;

  測試:對test_tb表施加寫鎖

Mariadb之顯式使用表鎖和行級鎖

  提示:釋放鎖用unlock tables即可釋放剛才的讀鎖;

  測試:對test_tb進行寫操作,看看是否能夠進行?

Mariadb之顯式使用表鎖和行級鎖

  提示:在目前終端(加寫鎖所在終端)上是可以進行讀寫操作的;

  測試:在其他終端看看是否能夠對test_tb表進行讀寫操作呢?

Mariadb之顯式使用表鎖和行級鎖

  提示:從上面的截圖可以看到當我們重新啟動一個終端對test_tb進行寫操作,它一直處于阻塞狀态;

Mariadb之顯式使用表鎖和行級鎖

  提示:對于對操作也是同樣的效果;一直阻塞着;

  總結:對于施加讀鎖的表,是可以進行讀操作的,但是不能進行寫操作,包括目前終端也不能寫操作;對于施加寫鎖的表,在目前施加鎖的終端上是可以對其進行讀寫操作的,但是在别的終端讀寫操作都将阻塞;

  除了以上指令來對表進行加鎖外,還可以使用 flush tables指令來加讀鎖,具體文法請看下面;

  FLUSH TABLES tbl_name,... [WITH READ LOCK];

  測試:加讀鎖

Mariadb之顯式使用表鎖和行級鎖

  提示:以上flush tables 隻能加讀鎖,不能加寫鎖;

  行級鎖:SELECT cluase [FOR UPDATE | LOCK IN SHARE MODE]

  行級排它鎖

Mariadb之顯式使用表鎖和行級鎖

  提示:以上紅框中的内容就是給第一行加了一個排它鎖,這意味着該事務沒有送出,其他事務就不能再擷取該行的其他鎖,包括共享鎖和排它鎖,但是擷取排它鎖的事務是可以對資料就行讀取和修改。

Mariadb之顯式使用表鎖和行級鎖

  提示:可以看到我們重新啟動一個事務,然後對第一行進行更新操作,語句就阻塞在哪裡了;說明行級排它鎖對其他事務來講是不允許對加鎖的行進行寫操作;預設情況updeate更新會預設加上排它鎖,因為對于第一行來講,已經有一個排它鎖了,是以其他事務就不能對其在加其他鎖;而對于select語句來講,它執行時預設會加任何鎖的,是以我們執行select語句是可以正常的檢視第一行資料;如果我們在select後面手動加鎖,它也會阻塞的;如下

Mariadb之顯式使用表鎖和行級鎖

  提示:從上面的截圖資訊可以看到,我們手動加上排它鎖,查詢語句也不會順利執行;從上面資訊還可以了解到,我們對第二行也沒法進行操作,這又是為什麼呢?

Mariadb之顯式使用表鎖和行級鎖

  提示:我們檢視test_tb這張表上的索引資訊,發現沒有索引,然後我們在上面建立了一個索引;建立索引時,需要把前面的事務送出了,才可建立成功,否則一直鎖在哪裡的;接下來我們在建立一個事務,把第一行加上排它鎖,然後在對第二行操作看看是否還會一直阻塞呢?

Mariadb之顯式使用表鎖和行級鎖
Mariadb之顯式使用表鎖和行級鎖

  提示:可以看到當我們建立就了索引後,再對第一行加鎖,然後更新第二行就可以正常更新了 ,對第一行還是處于阻塞狀态;這說明innodb存儲引擎的行級鎖的實作其實是依靠其對應的索引,是以如果操作的行并沒有用到索引,那麼用的還是表級鎖。施加行級排它鎖後,其他事務将不能對其在施加任何鎖;那麼對于擷取到排它鎖的是否能夠正常操作呢?

Mariadb之顯式使用表鎖和行級鎖

  提示:對于擷取到排它鎖的事務,是可以正常更新修改的;也可以給對應行施加其他鎖;

  行級共享鎖

Mariadb之顯式使用表鎖和行級鎖

  提示:以上紅框中的内容表示給第一行施加共享鎖,這意味着在其他事務鎖可以共享這把鎖看到資料,但是不能更新修改資料;

  測試:在目前事務中更新資料,看看是否可更新?

Mariadb之顯式使用表鎖和行級鎖

  提示:在目前事務中是可以正常修改資料的;也能正常檢視資料;

  在其他事務中修改資料,看看是否可修改?

Mariadb之顯式使用表鎖和行級鎖

  提示:可以看到在其他事務中,就不能對有共享鎖的行進行修改操作,但是可以正常讀;

  總結:innodb存儲引擎的行級鎖依賴索引,如果沒有索引,就相當于表級鎖;對于排它鎖來講,擷取到排它鎖的事務是可以正常修改更新以及加共享鎖,對于沒有擷取到排它鎖的事務,是不能夠對有鎖的行進行修改更新以及加鎖的操作;對于共享鎖來講,對于目前事務(加鎖操作的事務)是可以正常修改更新有鎖的行,對于其他事務,是不可修改和更新有鎖的行;

作者:Linux-1874

出處:https://www.cnblogs.com/qiuhom-1874/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.