天天看點

MySQL事務隔離級别

  事務有 acid 四個基本屬性:原子性(atomicity)、一緻性(consistency)、隔離性(isolation)和持久性(durability)

事務就是要保證一組資料庫操作,要麼全部成功,要麼全部失敗;

在 mysql 中,事務支援是在引擎層實作的;

并不是所有引擎都支援事務,如 myisam 就不支援,innodb 就支援;

  髒讀(dirty read),簡單來說,就是一個事務在處理過程中讀取了另外一個事務未送出的資料。這種未送出的資料我們稱之為髒資料。依據髒資料所做的操作肯能是不正确的。

  不可重複讀(non-repeatable read),是指一個事務範圍内,多次查詢某個資料,卻得到不同的結果。在第一個事務中的兩次讀取資料之間,由于第二個事務的修改,第一個事務兩次讀到的資料可能就是不一樣的。

  髒讀和不可重複讀的差別:髒讀是某一事務讀取了另外一個事務未送出的資料,不可重複讀是讀取了其他事務送出的資料。

  幻讀(phantom read),是事務非獨立執行時發生的一種現象。

  例如事務 t1 對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務 t2 又對這個表中插入了一行資料項為“1”的資料,并且送出給資料庫。而操作事務 t1 的使用者如果再檢視剛剛修改的資料發現還有1。

  幻讀和不可重複讀:幻讀和不可重複讀都是讀取了另一條已經送出的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。

  花費最高代價但最可靠的事務隔離級别。讀寫都加鎖。事務 100% 隔離,可避免髒讀、不可重複讀、幻讀的發生。

  多次讀取同一範圍的資料會傳回第一次查詢的快照,即使其他事務對該資料做了更新修改。事務在執行期間看到的資料前後必須是一緻的。

  但如果這個事務在讀取某個範圍内的記錄時,其他事務又在該範圍内插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會産生幻行,這就是幻讀。

  可避免髒讀、不可重複讀的發生。但是可能會出現幻讀

  保證一個事物送出後才能被另外一個事務讀取。另外一個事務不能讀取該事物未送出的資料。可避免髒讀的發生,但是可能會造成不可重複讀。

read uncommitted (讀未送出)

  最低的事務隔離級别,一個事務還沒送出時,它做的變更就能被别的事務看到。

  事務隔離級别越高,越能保證資料的完整性和一緻性,但是付出的代價卻是并發執行效率的低下。

  事務的機制是通過視圖(read-view)來實作的并發版本控制(mvcc),不同的事務隔離級别建立讀視圖的時間點不同。

可重複讀是每個事務重建讀視圖,整個事務存在期間都用這個視圖。

讀已送出是每條 sql 建立讀視圖,在每個 sql 語句開始執行的時候建立的。隔離作用域僅限該條 sql 語句。

讀未送出是不建立,直接傳回記錄上的最新值

串行化隔離級别下直接用加鎖的方式來避免并行通路。

  這裡的視圖可以了解為資料副本,每次建立視圖時,将目前已持久化的資料建立副本,後續直接從副本讀取,進而達到資料隔離效果。