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}