1. 程式人生 > >mysql資料庫隔離級別及其原理

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結束。