mysql資料庫隔離級別及其原理
一、事務的基本要素(ACID)
1、原子性(Atomicity):事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是一個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。
2、一致性(Consistency):事務開始前和結束後,資料庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。
3、隔離性(Isolation):同一時間,只允許一個事務請求同一資料,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。
4、永續性(Durability):事務完成後,事務對資料庫的所有更新將被儲存到資料庫,不能回滾。
二、事務的併發問題
1、髒讀:一個事務讀取另外一個事務還沒有提交的資料叫髒讀【針對未提交的資料】
2、不可重複讀:即在同一個事務內,兩個相同的查詢返回了不同的結果【讀取資料本身的對比】
表tms_message_info資料:
ID file_name
1 1111.SND
2 2222.SND
事務A READ-COMMITTED | 事務B READ-COMMITTED |
start transaction; select * from tms_message_info where id='1' |
start transaction;-- 開啟事務 update tms_message_info set FILE_NAME='666.SND' where ID='1'; 未提交 |
B事務未提交前,A事務執行上述查詢,得到的檔名結果為1111.SND | commit; B 事務提交 |
B事務提交後,A事務在執行查詢,結果發生變化,檔名變為666.SND,即同一事務查詢結果不同,即不可重複讀 |
3、幻讀:系統管理員A將資料庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
【同一事務A多次查詢,若另一事務B只是update,則A事務多次查詢結果相同;若B事務insert/delete資料,則A事務多次查詢就會發現新增或缺少資料,出現幻讀,即幻讀關注讀取結果集條數變化】
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
三、MySQL事務隔離級別
1、讀不提交(Read Uncommited,RU)
這種隔離級別下,事務間完全不隔離,會產生髒讀,可以讀取未提交的記錄,實際情況下不會使用。
2、讀提交(Read commited,RC)
本事務讀取到的是最新的資料(其他事務提交後的)。問題是,在同一個事務裡,前後兩次相同的SELECT會讀到不同的結果(不重複讀)
3、可重複讀(Repeatable Read,RR)【MySQL 預設的級別】
在同一個事務裡,SELECT的結果是事務開始時時間點的狀態,因此,同一個事務同樣的SELECT操作讀到的結果會是一致的。但是,會有幻讀現象
4、 序列化(SERIALIZABLE)。讀操作會隱式獲取共享鎖,可以保證不同事務間的互斥
四、4種隔離級別的相應原理總結如下:
READ_UNCOMMITED 的原理:
- 事務對當前被讀取的資料不加鎖;
- 事務在更新某資料的瞬間(就是發生更新的瞬間),必須先對其加 行級共享鎖,直到事務結束才釋放。
表現:
- 事務1讀取某行記錄時,事務2也能對這行記錄進行讀取、更新;當事務2對該記錄進行更新時,事務1再次讀取該記錄,能讀到事務2對該記錄的修改版本,即使該修改尚未被提交。
- 事務1更新某行記錄時,事務2不能對這行記錄做更新,直到事務1結束。
READ_COMMITED 的原理:
- 事務對當前被讀取的資料加 行級共享鎖(當讀到時才加鎖),一旦讀完該行,立即釋放該行級共享鎖;
- 事務在更新某資料的瞬間(就是發生更新的瞬間),必須先對其加 行級排他鎖,直到事務結束才釋放。
表現:
- 事務1讀取某行記錄時,事務2也能對這行記錄進行讀取、更新;當事務2對該記錄進行更新時,事務1再次讀取該記錄,讀到的只能是事務2對其更新前的版本,要不就是事務2提交後的版本。
- 事務1更新某行記錄時,事務2不能對這行記錄做更新,直到事務1結束。
REPEATABLE READ 的原理:
- 事務在讀取某資料的瞬間(就是開始讀取的瞬間),必須先對其加 行級共享鎖,直到事務結束才釋放;
- 事務在更新某資料的瞬間(就是發生更新的瞬間),必須先對其加 行級排他鎖,直到事務結束才釋放。
表現:
- 事務1讀取某行記錄時,事務2也能對這行記錄進行讀取、更新;當事務2對該記錄進行更新時,事務1再次讀取該記錄,讀到的仍然是第一次讀取的那個版本。
- 事務1更新某行記錄時,事務2不能對這行記錄做更新,直到事務1結束。
SERIALIZABLE 的原理:
- 事務在讀取資料時,必須先對其加 表級共享鎖 ,直到事務結束才釋放;
- 事務在更新資料時,必須先對其加 表級排他鎖 ,直到事務結束才釋放。
表現:
- 事務1正在讀取A表中的記錄時,則事務2也能讀取A表,但不能對A表做更新、新增、刪除,直到事務1結束。
- 事務1正在更新A表中的記錄時,則事務2不能讀取A表的任意記錄,更不可能對A表做更新、新增、刪除,直到事務1結束。