mysql數據庫鎖簡介


本篇介紹有關數據庫鎖相關的知識,關於數據庫事務及隔離級別參見《數據庫事務ACID特性及隔離級別》這篇文。
 
樂觀鎖
樂觀鎖最常用的實現方式是用數據版本(Version)記錄機制。數據版本即為數據增加一個版本標識,一般通過在數據庫表中增加一個數字類型的 “version” 字段實現。讀取數據時將version字段值一同讀出,數據每更新一次,對version值加1,提交更新時將數據庫表對應記錄的當前version值與已取出的version值進行比對,如果數據庫表當前version值與已取出的version值相等,則可以更新,否則認為是過期數據。
 
通常在實際項目中涉及金錢類的可能會使用這種樂觀鎖。
 
舉例:
1、數據庫表三個字段,分別是id、value、version
select id,value,version from table1 where id = #{id}
2、每次更新表中的value字段時為了防止發生沖突,需要這樣操作
update table1
set value=2,version=version+1
where id=#{id} and version=#{version}
 
悲觀鎖
悲觀鎖認為在操作數據時會出現數據沖突,每次都要通過獲取鎖才能對相同數據進行操作,所以悲觀鎖需要耗費較多的時間。共享鎖排它鎖 是悲觀鎖的不同實現,都屬於悲觀鎖的范疇。
 
1、鎖的粒度
 

InnoDB默認采用行鎖,在未使用索引字段查詢時升級為表鎖行鎖可能因為未使用索引而升級為表鎖,所以除了檢查索引是否創建的同時,也需要通過explain執行計划查詢索引是否被實際使用。

 
2、讀寫鎖

3、意向鎖(Intention Locks)

為了實現多粒度鎖機制,協調 行級讀寫鎖 和 表級讀寫鎖 (也就是不同粒度)之間的關系。意向鎖是一種允許 行鎖表鎖 共存的表鎖。意向鎖是由數據庫引擎維護的,用戶無法手動操作。在為數據行加 共享鎖 / 排它鎖 之前,InooDB 會先獲取該數據行所在數據表的對應 意向鎖。意向鎖只會阻塞全表請求,主要目的是展示正在鎖定表中一行,或者將要鎖定一行。
 
意向鎖分為兩種:
 
意向共享鎖(intention shared lock, IS):事務有意向對表中的某些行加共享鎖(S鎖)
-- 事務要獲取某些行的 S 鎖,必須先獲得表的 IS 鎖。
SELECT column FROM table1 ... LOCK IN SHARE MODE;
 
意向排它鎖(intention exclusive lock, IX):事務有意向對表中的某些行加排它鎖(X鎖)
-- 事務要獲取某些行的 X 鎖,必須先獲得表的 IX 鎖。
SELECT column FROM table1 ... FOR UPDATE;
 
意向鎖不會與行級的 共享/排它鎖 互斥。

1) InnoDB 支持多粒度鎖,特定場景下,行級鎖 可以與 表級鎖 共存。

2) 意向鎖之間互不排斥,但除了 IS 與 S 兼容外,意向鎖會與 共享鎖 / 排它鎖 互斥。
3) IX,IS是表級鎖,不會和行級的X,S鎖發生沖突。只會和表級的X,S發生沖突。
4) 意向鎖在保證並發性的前提下,實現了行鎖和表鎖共存且滿足事務隔離性的要求。
 
4、記錄鎖(Record Locks)
記錄鎖是在索引記錄上的鎖。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 防止任何其他事務 插入、更新 或 刪除 t.c1=10 的行。
 
5、間隙鎖(Gap Locks)
間隙鎖(gap)是索引記錄之間上的鎖,或者說第一個索引記錄之前或最后一個索引記錄之后的間隔上的鎖。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止其他事務插入 t.c1 = 15 的記錄,不管是否已經有這種值在本列中,因為這個范圍內的所有值都被上鎖了。
 
6、NK鎖(Next-Key Locks)
NK鎖是記錄鎖和間隙鎖的組合,鎖定一個范圍,並且鎖定記錄本身。對查詢范圍進行加鎖,在另一個事務執行插入操作時是不被運行的,從而避免了幻讀。用於解決幻讀問題。
 
InnoDB默認的事務隔離級別是Repeatable Read,此時InnoDB使用NK鎖進行搜索和索引掃描,防止產生幻讀
 
7、插入意向鎖(Insert Intention Locks)
插入意向鎖是在插入一條記錄行前,由 INSERT 操作產生的一種間隙鎖。該鎖用以表示插入意向,當多個事務在同一區間(gap)插入位置不同的多條數據時,事務之間不需要互相等待。
 
插入意向鎖本質上可以看成是一個間隙鎖(Gap Lock)。
 
普通的Gap Lock 不允許 在(上一條記錄,本記錄)范圍內插入數據
插入意向鎖Gap Lock 允許 在(上一條記錄,本記錄)范圍內插入數據
 
插入意向鎖的作用是為了提高並發插入的性能, 多個事務 同時寫入 不同數據 至同一索引范圍(區間)內不需要等待其他事務完成,不會發生鎖等待。
 
InnoDB 在 Repeatable Read 的事務隔離級別下,使用插入意向鎖來控制和解決並發插入。
 
8、自增鎖(AUTO-INC Locks)
自增鎖是由插入到具有AUTO_INCREMENT列的表中的事務所采用的特殊表級鎖。 在最簡單的情況下,如果一個事務正在向表中插入值,任何其他事務必須等待,以便這個事務獲得連續的主鍵值。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com