[TOC](【後端面經-資料庫】MySQL的事務隔離級別簡介) ## 0. 事務的概念 事務指的是一連串的集中操作指令,一個事務的執行必須執行完所有的動作才能算作執行結束。事務具有四個特點,簡記作`ACID`: - `A`-Atomicity: 原子性,事務的執行必須保證所有的動作都執行完畢; - ...
目錄
0. 事務的概念
事務指的是一連串的集中操作指令,一個事務的執行必須執行完所有的動作才能算作執行結束。事務具有四個特點,簡記作ACID
:
A
-Atomicity: 原子性,事務的執行必須保證所有的動作都執行完畢;C
-Consistency: 一致性,事務的執行必須保證數據的一致性;I
-Isolation: 隔離性,事務的執行必須保證數據的隔離性;D
-Durability: 持久性,事務的執行必須保證數據的持久性。
而事務隔離級別則是在大型資料庫多個事務執行的過程中,針對事務並行進行的機制設計,主要是圍繞Isolation
進行設計的。
1. 三類問題
- 臟讀
- 過程:
- 事務A正在寫某一行數據,未提交;
- 事務B並行讀取該行數據,用於操作;
- 事務A撤銷寫操作,這是對於事務B來說,之前的讀操作就是錯誤的。
- 讀事務讀取了寫事務未提交的數據,而造成錯誤讀取。
- 舉例
- 小明今天發工資,一開始在財務系統上查詢是工資50000元,很高興地準備買新電腦,但是這是財務正在敲數據的時候一時疏忽,實際上工資只有5000元,財務在審核數據準備提交的時候發現了這個錯誤並修改過來,小明很失望。
- 這裡的小明就是
讀事務
,財務就是寫事務
。
- 過程:
- 不可重覆讀
- 過程:
- 事務B讀取的是資料庫中的某一行數據,用於操作;
- 事務A開始對這行數據進行寫操作並完成,資料庫的數據改變;
- 事務B再次讀該資料庫的這一行數據,發現數據改變;
- 讀事務兩次讀同一行數據,但是兩次讀取的數據並不一致。
- 舉例
- 小明和小紅打賭,這個月工資是1k,兩個人幾乎同時發出查詢請求,但是小明先讀取到了原始數據是1k,而財務核對之後再次修改了工資為2k,小紅在這之後才併發讀取到工資是2k,兩人認為讀操作是並行的,同時進行,雖然知道這中間可能是財務進行了修改,但是兩人都認為自己讀取的才是最終數據,因此吵了起來。
- 過程:
- 幻讀
- 過程
- 事務B讀取資料庫中的一批數據,用於操作;
- 事務A添加了一行數據,並完成操作,資料庫的數據改變;
- 事務B再次讀該資料庫的數據,發現這一批數據改變;
- 讀事務兩次讀取同一行數據,但是兩次讀取的數據不一致。(這和
不可重覆讀
操作是一致的)。 - 舉例
- 小明被領導要求,改動財務系統上的ID數據格式,從A格式全都轉為B格式,小明讀取資料庫中的數據之後開始修改,這時候,財務發現新來了一位員工叫小紅,於是把小紅的記錄添加在財務系統上,ID格式依然是A格式。小明工作完成之後給領導看,領導卻發現有一個人的數據沒有改過來,很是惱火,把小明批評了一番。
- 幻讀和不可重覆讀的區別
- 幻讀是針對同一批數據,不可重覆讀針對的是同一行數據
- 過程
2. 事務隔離級別
- 讀未提交(read uncommitted)
- 一個事務在寫某一行數據的時候,允許其他事務並行讀取該行數據,但是不允許寫該行數據;
- 允許多個事務並行讀取資料庫中的數據,但是不允許並行寫入某一行數據;
- 可能會出現
臟讀
: - 解決方案:排他鎖
-
讀已提交(read committed)
- 一個事務在寫某一行數據的時候,不允許其他事務讀或者寫該行數據;
- 允許多個事務並行讀取資料庫的數據;
- 可能都造成
不可重覆讀
:
-
可重覆讀(repeatable read)
- 一個事務在讀數據的時候,其他事務不允許寫,可以讀。
- 一個事務在寫數據的時候,其他事務不可以讀或者寫。
- 可能會造成
幻讀
: - MySQL預設的隔離級別。
-
串列化(serializable)
- 一個事務一個事務串列執行,不允許任何事物並行;
- 能夠解決
幻讀
、不可重覆讀
、臟讀
的問題; - 成本高,一般不適用
3. 操作指令
- 查看當前的隔離級別
SELECT @@tx_isolation;
- 設置隔離級別
set [glogal | session] transaction isolation level 隔離級別名稱;//方式1 set tx_isolation='隔離級別名稱';//方式2 ``
4. 總結
對前期的事務隔離級別做一個表格梳理