Transaction Isolation Levels
InnoDB支援SQL1992標準中的四種隔離級別:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。預設的隔離級別是REPEATABLE READ。
通過SET TRANSACTION命令可以改變預設的隔離級別,為了讓這種改變對所有使用者的所有連線都生效,需要加上--transaction-isolation選項。
InnoDB通過不同的加鎖策略來實現不同的隔離級別
REPEATABLE READ
這是InnoDB預設的隔離級別。在一個事務中,一致讀會讀到該事務中第一次讀到的那個快照。這就意味著,在同一個事務中多次執行普通的SELECT語句返回的結果是一致的。
對於加鎖讀(SELECT ... FOR UPDATE或者SELECT ... LOCK IN SHARE MODE)、更新、刪除語句,鎖取決於語句是否使用了唯一索引或者範圍類的檢索條件。
- 對於用唯一索引作為檢索條件,InnoDB只會鎖發現的索引記錄,而不會鎖它前面的間隙
- 對於其它的檢索條件,InnoDB鎖定掃描的索引範圍,用間隙鎖或者next-key鎖來阻塞其它會話向這個範圍內的間隙中插入資料
參考 https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html
事務的特性
- 原子性:事務中的操作要麼全部成功,要麼全部失敗
- 一致性:事務操作必須是將資料庫從一個一致性狀態帶到另一個一致性狀態。所謂一致指的是,比如轉賬,A和B都有100元,轉賬之前總共是200元,轉賬之後必須也是200元
- 隔離性:事務之間不會相互影響
- 永續性:事務提交以後對資料庫所做的改變將永久儲存下來
事務併發帶來的問題
- 髒讀:一個事務讀到另一個事務未提交的資料
- 幻讀:一個事務讀到另一個事務已提交的資料,然而這種提交的資料涉及到整個表,比如插入和刪除,看起來好像幻覺一樣
- 不可重複讀:一個事務中多次讀取同一個資料返回的結果不一樣
事務隔離級別
- 讀未提交:允許一個事務看到另一個事務沒有提交的資料
- 讀已提交:允許一個事務看到另一個事務已提交的資料
- 可重複讀:同一個事務中多次讀取看到的資料始終一致
- 序列化:併發事務序列執行