天天看點

MySQL事務隔離級别

事務的基本特性

  • 原子性 (Atomicity):事務的操作要麼一起成功,要麼一起失敗。如果執行過程中出錯,需要復原到之前的狀态。
  • 一緻性 (Consistency):事務完成前後,資料庫的完整性限制不能被破環。例如A給B轉賬,不能A扣了錢,B卻沒有收到錢,此時的金額總數也不一緻。
  • 隔離性 (Isolation):同一時間,隻允許一個事務請求統一資料,不同僚務間應該互相幹擾。例如A在銀行取錢,在其取錢過程結束前,其他人不能像這張卡轉賬。
  • 持久性 (Durability):事務完成之後,資料的更改将持久化到資料庫中,不可復原。

四種隔離級别對髒讀、不可重複讀、幻讀的解決程度

事務隔離級别 髒讀 不可重複讀 幻讀
讀未送出 (READ-UNCOMMITTED) 可能
不可重複讀/讀送出(READ-COMMITTED) 不可能
可重複讀(REPEATABLE-READ)
串行化 (SERIALIZABLE)

這四種級别由上至下,隔離強度逐漸增強,性能逐漸變差。它們沒有絕對的優劣,采取哪種應該根據系統需求決定。MySQL預設級别為:可重複讀。

串行化是4種事務隔離級别中隔離效果最好的,解決了髒讀、可重複讀、幻讀的問題,但是效果最差,它将事務的執行變為順序執行,與其他三個隔離級别相比,它就相當于單線程,後一個事務的執行必須等待前一個事務結束。

髒讀、可重複讀、不可重複讀與幻讀

  • 髒讀:在一個事務中讀到了另一個事務修改但未送出的資料,這些資料可能會復原即最終可能不會持久化到資料庫中。簡言之,讀到了并不一定最終存在的資料。
  • 可重複讀:在一個事務内的任意時刻,讀到的同一批資料是一緻的。即不受其他事務修改資料的影響,即使其他事務已經修改資料并送出事務,本事務讀到的資料依然和之前一緻。通常針對UPDATE操作。
  • 不可重複讀(讀送出):在一個事務内,不同時刻讀到的同一批資料可能是不同的。若其他事務已經修改資料并送出事務,此時讀到的便是其他修改後的資料。通常針對UPDATE操作。
  • 幻讀:在一個事務中,查詢同一批資料,但後面的查詢查到了前面沒有查到的行。這是由于其他事務中插入資料造成的,通常針對INSERT操作。

MySQL在其預設隔離級别即可重複讀狀态下已經解決了幻讀問題。

不要混淆幻讀與不可重複讀,兩者極其相似。但是前者針對INSERT操作,後者針對UPDATE操作。

SQL操作

  • 檢視隔離級别
select @@transaction_isolation;
# 或者使用模糊查詢,查詢變量
show variables like '%_isolation%';
           
  • 更改隔離級别
set session transaction isolation level read uncommitted;
# session為事務隔離級别的範圍,即目前會話。
# 與之對應的還有global,即全局範圍。global設定的範圍隻對新的session視窗有效,修改之前已經開啟的會話不受影響。
# read uncommitted為設定的隔離級别——讀未送出。
           
  • 事務操作相關SQL語句
# 開啟事務
start transaction;
# 事務復原 
rollback;
# 事務送出
commit;