MySQL系列之二四種隔離級別及加鎖
事務
1、定義:所有操作必須成功完成,否則在每個操作中所作的所有更改都會備撤銷。
2、事務的ACID
原子性atomicity 一致性consistency 隔離性isolation 持續性durability
2-1、原子性: 事務是數據庫的邏輯工作單位,事務中包含的各操作要麽都做,要麽都不做
2-2、一致性: 事務執行的結果必須是數據庫從一個一致性狀態變到另一個一致性狀態。因此當數據庫只包含成功事務提交的結果時,
就說明數據庫處於一致性狀態。
2-3、隔離性: 一個事務的執行不能被其他事務幹擾。
2-4、持續性: 即永久性,一個事務一旦提交,它對數據庫中數據的改變就應該是永久行的。
3、MySQL的四中隔離級別
3-1、read uncommitted(讀取未提交的內)
所有事務都可以看到其他未提交事務的執行結果。 也稱之為臟讀,很少應用與實際
3-2、read committed(讀取提交內容)
一個事務只能看見已提交事務所做的改變。
3-3、repeatable read(可重復讀)
MySQL默認事務隔離級別,確保同一事務的多個實例在並發讀取數據時,會看到同樣的數據行。不過,會導致幻讀。
幻讀指用戶讀取某一範圍數據行時,另一個事務又在該範圍內插入了新行。當用戶再讀取該範圍的數據行時,會發現出現新的幻影行
3-4、serializable(可串行化)
在每個讀的數據行上加上共享鎖。這個級別可能導致大量的超時現象和鎖競爭。
4、事務隔離的原理
1、一次封鎖or兩段鎖
在大量並發訪問時候,為了預防死鎖,一般應用中推薦使用一次封鎖法,就是在方法的開始階段,已經預先知道會用到哪些數據,
然後全部鎖住,在方法運行之後,在全部解鎖。但這種方式不適用於數據庫,因為數據庫不知道會用到哪些數據。
數據庫采用的是兩段鎖協議,將事務分成兩個階段,加鎖階段和解鎖階段。
加鎖階段: 在對任何數據進行讀操作之前要申請並獲得S鎖(共享鎖,其他事務可以繼續加共享鎖,但不能加排它鎖),在進行寫
操作之前要申請X鎖(排它鎖,其他事務不能再獲得任何鎖)。如果加鎖不成功的話,則事務進入等待狀態,直到加鎖成功才能繼續執行。
解鎖階段: 當事務釋放了一個封鎖以後,事務進入解鎖階段,在該階段只能進行解鎖操作不能再解析加鎖操作。
不可重復讀與幻讀的區別:
不可重復讀重點在於update和delete,而幻讀在於insert
5、mvcc在MySQL的innodb實現
在innodb中,會在每行數據後添加兩個額外的隱藏的值來實現MVCC,這兩個值一個記錄這行數據何時被創建,另一個記錄這行
數據何時過期(或者被刪除)在實際操作中,存儲的並不是時間,而是事務的版本號,每開啟一個新事務,事務的版本號就會
遞增。在可重復讀的事務隔離級別下:
select時,讀取創建版本號不大於當前事務版本好,刪除版本號為空或大於當前事務版本號
insert時,保持當前事務版本號為行的創建版本號
delete時,保持當前版本號為行的刪除版本號
update時,插入一條新記錄,保存當前事務版本號為行創建的版本號,同時保持當前事務版本號到原來刪除的行
MySQL系列之二四種隔離級別及加鎖