1. 程式人生 > >InnoDB中事務隔離級別和鎖的關係 思路?個人理解?

InnoDB中事務隔離級別和鎖的關係 思路?個人理解?

1
資料庫遵循兩段鎖協議,加鎖階段和解鎖階段,在對任何資料進行讀操作之前要申請並獲得S鎖,在寫操作之前要申請並獲得X鎖

2
事務中的加鎖方式,事務的四種隔離級別,未提交讀,已提交讀(RC),可重複讀(RR),可序列化,各種隔離級別對應的髒讀,不可重複讀和幻讀

3
鎖的種類:行鎖 表鎖
重點講行鎖,由於行鎖只鎖住有限的資料,對於其它資料不加限制,所以併發能力強,MySQL一般都是用行鎖來處理併發事務

4
在RC(不可重讀)級別中,資料的讀取都是不加鎖的,但是資料的寫入、修改和刪除是需要加鎖的,在有索引的情況下mysql會過濾掉不符合條件的行,給符合條件的行加鎖,如果沒有索引的增刪改理論上則會鎖住全表,實際操作上mysql做了一些改進,在過濾條件不滿足後,會呼叫unlock row方法,把不滿足條件的記錄釋放鎖,保證了最後只會持有滿足條件記錄上的鎖,但是每條記錄的加鎖操作還是不能省略的

5
在RR級別中,RR是MySQL中InnoDB預設的隔離級別,可重讀這個概念是一事務的多個例項在併發讀取資料時,會看到同樣的資料行,如何實現,第一次select一部分資料後,用悲觀鎖鎖定這些資料,其他事務無法修改這些資料,就可以實現可重複讀,但是效率低,而且鎖不住insert進去的資料,會出現幻讀,mysql用樂觀鎖mvcc(多版本併發控制)來避開這兩種問題

6
MVCC 基於資料版本( Version)記錄機制實現,讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。類似CAS的過程

7
MVCC在innodb中的讀(快照讀)安全的實現,在InnoDB中,會在每行資料後新增兩個額外的隱藏的值來實現MVCC,這兩個值一個記錄這行資料何時被建立,另外一個記錄這行資料何時過期(或者被刪除),這兩個值就是事務的版本號,保證了可重複讀和去除了幻讀(即使在InnoDB開啟RR級別的情況下)

8
MVCC中併發提交資料時會出現衝突,那麼衝突時如何解決呢?(其實就是解決當前讀的安全問題)–>區分快照讀(讀取歷史資料,select,不需要加鎖)和當前讀(讀取當前版本資料,insert update delete時候的讀,需要加鎖)的區別–>MySQL為了減少鎖處理(包括等待其它鎖)的時間,提升併發能力,引入了快照讀的概念,使得select不用加鎖。而update、insert這些“當前讀”,就使用Next-Key鎖(GAP間隙鎖和行鎖的組合)–>RR級別中,事務A在update後加鎖,事務B無法插入新資料,這樣事務A在update前後讀的資料保持一致,避免了幻讀。這個鎖,就是Gap鎖–>根據索引的區間進行維護Gap鎖,將第一次查詢出來的結果進行一個區間的維護,區間取查詢結果中的最小和最大值,在這個區間加鎖,非此區間的insert照樣可以插入,就避免了此區間的幻讀情況,如果沒有索引呢,就會全表上gap鎖