READ UNCOMMITTED(未提交)
即使沒有提交,對其它事務也可見。未提交的數據會引起髒讀(Dirty Read)。
測試流程:
1、A設置read-uncommitted, start transaction
2、B執行start transaction,修改一條記錄,
3、A查詢記錄,得到了以為正確的記錄
4、B回滾。
問題:A讀到了B沒有提交的記錄,也就是髒讀。
READ COMMITTED(提交讀)
一個從開始直到提交之前所做的任何修改對其它事務都是不可見的。兩次同樣的查詢可能會得到不一樣的結果,稱為不可重復讀(nonrepeatable read)
測試流程:
1、A設置read-committed, start transaction
2、B執行start transaction,修改一條記錄,查詢記錄,記錄已經修改成功
3、A查詢記錄,結果還是老的記錄
4、B提交事務
5、A再次查詢記錄,結果是新的記錄。
問題:兩次查詢結果不一致,也就是不可重復讀問題。
REPEATABLE READ(可重復讀)-MySQL默認的事務隔離級別
保證了在同一事務中多次讀取結果是一致的。但會引起另外一個幻讀問題,當某個事務在讀取某個范圍記錄時,另外一個事務在該范圍插入和新記錄,當之前事務再次讀取該范圍記錄時會產生幻行。
測試流程:
1、A設置repeatable-read, start transaction,查詢記錄,結果是老的記錄
2、B執行start transaction,修改一條記錄,查詢記錄,記錄已經修改成功
3、A查詢記錄,結果還是老的記錄
4、B提交事務
5、A再次查詢記錄,結果還是老的記錄。
問題:可以重復讀,A在事務過程中,即使B修改了數據,並且commit,A讀取的還是老的數據。即可重復讀。
注意:這裡可能會存在一個新的問題,A在事務過程中,B增加一條記錄,並提交,導致A的兩次讀取不一致,會多一條記錄,也就是幻影讀。InnoDB通過多版本並發控制(MVCC)解決了幻讀問題。
SERIALIZABLE(可串行化)
強制事務串行執行,但可能導致大量超時和鎖爭問題。
測試流程:
1、A設置serializable, start transaction,查詢記錄,結果是老的記錄
2、B執行start transaction,修改一條記錄,B卡在這裡,要等待A完成才行。
3、A查詢記錄,結果還是老的記錄,A提交。
4、B的修改操作才進行下去。
注意:B在等待過程中,會出現lock超時。
MySQL事務隔離級別總結:
MySQL事務隔離級別介紹及設置
MySQL事務隔離級別操作
查看當前會話隔離級別:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.12 sec)
查看當前系統隔離級別:
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
設置隔離級別語法:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}