(16)mysql 中的表鎖定及事務控制

概述

MySQL支持三種鎖級別:頁級表級行級。MyISAM和MEMORY存儲引擎採用的是表級鎖(table-level locking);BDB存儲引擎採用的是頁面鎖(page-level locking),但也支持表級鎖;InnoDB存儲引擎既支持行級鎖(row-level locking),也支持表級鎖,但默認狀況下是採用行級鎖。在默認狀況下,表鎖和行鎖都是自動獲取的,不須要額外的命令。三種鎖級別優缺點以下:html

  • 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低。
  • 頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常。
  • 行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。

表鎖定

1.語法

#鎖定表
LOCK TABLES 
    tb_name1 [AS alias] {READ[LOCAL]|[LOW_PRIORITY] WRITE}
    tb_name2 [AS alias] {READ[LOCAL]|[LOW_PRIORITY] WRITE}
    ...
#釋放表鎖定
UNLOCK TABLES;複製代碼
  • lock tables 能夠鎖定用於當前線程(會話)的表。若是被其餘線程鎖定,則當前線程會等待,直到能夠獲取全部鎖定爲止。
  • unlock tables釋放當前線程(會話)得到的任何鎖定。
  • read(讀鎖/共享鎖):當表不存在 WRITE 寫鎖時 READ 讀鎖被執行,這該狀態下,當前線程不能夠修改(insert,update,delete),其餘線程的修改操做進入列隊,噹噹前線程釋放鎖,其餘線程修改被執行。
  • read local:read local和read之間的區別是,read local容許在鎖定被保持時,執行非衝突性INSERT語句(同時插入)。可是,若是您正打算在MySQL外面操做數據庫文件,同時您保持鎖定,則不能使用read local。對於InnoDB表,read local與read相同。
  • write(寫鎖/排它鎖):除了當前用戶被容許讀取和修改被鎖表外,其餘用戶的全部訪問(讀/寫)被徹底阻止。注意的是在當前線程當WRITE被執行的時候,即便以前加了READ沒被取消,也會被取消。
  • low_priority write:下降優先級的write,默認write的優先級高於read.假如當前線程的low_priority write在列隊裏面,在未執行以前其餘線程傳送一條read,那麼low_priority write繼續等待.
  • InnoDB行鎖是經過給索引上的索引項加鎖來實現的,這一點MySQL與Oracle不一樣,後者是經過在數據塊中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖!
  • 併發插入:原則上數據表有一個讀鎖時,其它進程沒法對此表進行更新操做,但在必定條件下,MyISAM表也支持查詢和插入操做的併發進行。MyISAM存儲引擎有一個系統變量concurrent_insert,專門用以控制其併發插入的行爲,其值分別能夠爲0、1或2。
    • 當concurrent_insert設置爲0時,不容許併發插入。
    • 當concurrent_insert設置爲1時,若是MyISAM表中沒有空洞(即表的中間沒有被刪除的行),MyISAM容許在一個進程讀表的同時,另外一個進程從表尾插入記錄。這也是MySQL的默認設置。
    • 當concurrent_insert設置爲2時,不管MyISAM表中有沒有空洞,都容許在表尾併發插入記錄。

2.舉例

這是一個獲取表鎖及釋放表鎖的例子。其中session1和session2表示兩個同時打開的session(鏈接/線程),表格中的每一行表示同一時刻兩個session的運行狀況,後面的例子也是一樣的格式。
sql

表鎖舉例

事務控制

MySQL經過set autocommit、start transaction、commit、rollback等語句支持本地事務。數據庫

1.語法

START TRANSACTION |BEGIN [WORK]
COMMIT [WORK][AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK][AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT={0|1}複製代碼
  • 默認狀況下,MySQL是自動提交的,若是須要經過明確的Commit和Rollback來提交和回滾事務,那麼就須要經過明確的事務控制命令來開始事務。
  • start transaction 或begin語句開始一項新的事務。
  • commit和rollback用來提交或者回滾事務。
  • chain和release子句分別用來定義在事務提交或者回滾以後的操做,chain會當即啓動一個新事物,而且和剛纔的事務具備相同的隔離級別,release則會斷開和客戶端的鏈接。
  • set autocommit能夠修改當前鏈接的提交方式,若是設置了set autocommit=0,則設置以後的全部事務都須要經過明確的命令進行提交或者回滾。

2.舉例

舉例一
使用start transaction和commit and chain。
session

事務控制1-1

事務控制1-2

事務控制1-3

舉例二
在鎖表期間,用start transaction命令開啓新事務,會形成隱含的unlock tables被執行。
併發

事務控制2-1

事務控制2-2

舉例三
在事務中能夠經過定義savepoint,指定回滾事務的一個部分,可是不能指定提交事務的一個部分。對於複雜的應用,能夠定義多個不一樣的savepoint,知足不一樣的條件時,回滾不一樣的savepoint。須要注意的是,若是定義了相同名字的savepoint,則後面定義的savepoint會覆蓋以前的定義。對於再也不須要使用的savepoint,能夠經過release savepoint命令刪除savepoint,刪除後的savepoint,不能再執行rollback to savepoint命令。
事務控制3-1

事務控制3-2

參考

blog.csdn.net/xiao7ng/art…
www.cnblogs.com/huangye-dre…
c.biancheng.net/cpp/html/14…spa

相關文章
相關標籤/搜索