Mysql隔離級別詳解
資料庫隔離級別為資料庫事務四大基本特性:原子性、一致性、隔離性、永續性其中之一,並且是其中最難理解和重要的特性,這裡對個人對於隔離級別的理解做出記錄
測試過程中需要使用到的sql語句
#設定資料庫隔離級別,但是需要注意的是此設定只對當前會話生效 set tx_isolation='READ-UNCOMMITTED'; #確認設定是否成功 select @@tx_isolation; 或者 show variables like 'tx_isolation'; #查詢未提交事務 SELECT trx_mysql_thread_id FROM information_schema.INNODB_TRX #結束未提交事務 KILL ID
一、READ_UNCOMMITTED(未提交讀):能夠在當前事務中讀取到其它未提交事務中更新的資料,當其它事務回滾後之前讀到的資料變為髒資料,又稱為髒讀
事務1 | 事務2 | 結果 |
SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; UPDATE red_record SET total=6 WHERE id=1; SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; SELECT * FROM red_record WHERE id=1; | 讀取到了事務1中未提交的更新資料 | |
COMMIT; | ||
SELECT * FROM red_record WHERE id=1; | ||
COMMIT; |
二、READ-COMMITTED(提交讀):當前事務只能讀取到其它事務提交的資料,但是會出現同一個事務查詢同一條記錄結果不一樣,又稱為不可重複讀
事務1 | 事務2 | 結果 |
SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; UPDATE red_record SET total=6 WHERE id=1; SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; SELECT id,total FROM red_record WHERE id=1; | ||
COMMIT; | ||
SELECT id,total FROM red_record WHERE id=1; | 出現同一個事務中對同一條記錄讀取的結果不一樣 | |
COMMIT; |
三、REPEATABLE-READ(可重複讀):保證了在同一個事務中多次讀取同一條記錄的結果保持一致,但是會出現幻讀,當某個事務在讀取某個範圍內的資料時有新的記錄插入,當再次讀取這個範圍內的資料時會出現幻行
事務1 | 事務2 | 結果 |
SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; UPDATE red_record SET total=6 WHERE id=1; SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; SELECT id,total FROM red_record WHERE id=1; | ||
COMMIT; | ||
SELECT id,total FROM red_record WHERE id=1; | ||
COMMIT; |
四、SERIALIZABLE(可序列化):SERIALIZABLE隔離級別最高,它是通過強制事務序列化執行,避免了前面說的幻讀,會在讀取的每一行資料上都加鎖,所以會導致大量的超時和鎖爭用問
事務1 | 事務2 | 結果 |
BEGIN; SELECT id,total FROM red_record WHERE id=1; | ||
BEGIN; SELECT id,total FROM red_record WHERE id=1; | ||
UPDATE red_record SET total=6 WHERE id=1; | 等待事務1提交 | |
COMMIT; | ||
COMMIT; |