mysql數據庫隔離級別詳解
隔離級別
一、mysql有四個事務隔離級別
每個級別都有字符或數字編號
- 讀未提交 READ UNCOMMITTED | 0 : 存在臟讀,不可重復度,幻讀的問題。
- 讀已提交 READ COMMITTED | 1 : 解決臟讀問題,存在不可重復讀,幻讀的問題。
- 可重復讀 REPEATABLE READ | 2 : 解決臟讀,不可重復讀的問題,存在幻讀,默認隔離級別,使用MVCC機制實現可重復讀。
- 序列化 SERIALIZABLE | 3 : 解決臟讀,不可重復讀,幻讀,可保證事務安全,但完全串行執(zhí)行,性能最低。
我有記憶方法,先是RU、RC, 記住UC順序,聯想到UC WEB。
二、為什么默認RR隔離級別?
RR級別作為mysql事務默認隔離級別,是事務完全和性能的折中。SERIALIZABLE級別是悲觀地認為幻讀時刻都會發(fā)生,故會自動地隱式地對事務所需資源加排他鎖,其他事務訪問此資源會被阻塞等待,故事務是安全的,但需要認值考慮性能。
三、RR隔離級別下手動加鎖解決幻讀理論基礎
InnoDB的行鎖鎖定的是索引,而不是記錄本身。索引映射的記錄存在就加行鎖,如果不存在則會加next-key lock/gap鎖/間隙鎖, 故InnoDB可以實現事務對某記錄的預先占用。
臟讀、不可重復讀、幻讀 及其解決方法
臟讀
- 一個事務讀取到另一個事務還沒有提交的數據。解決方法:把事務隔離級別調整到READ COMMITTED。
不可重復讀
- 一個事務先后讀取同一條記錄,但兩次讀取的數據不同,我們稱之為不可重復讀。解決方法:把事務隔離級別調整到REPEATABLE READ。
幻讀
- 網上很多文章都說一個事務執(zhí)行范圍查詢,兩次select得到的條數不同,就叫幻讀,這是錯誤的?。?!
- 幻讀并不是說兩次讀取獲取的結果集不同,幻讀是指某一次select操作得到的結果所表征的數據狀態(tài)無法支持后續(xù)的業(yè)務操作,具體例子:select某記錄是否存在,不存在,準備插入此記錄,但執(zhí)行insert時發(fā)現此記錄已存在,無法插入,此時就發(fā)生了幻讀。
- 還一種理解思路,就是因為先采用了"快照讀",然后又用了"當前讀",發(fā)現結果不同。比如先select是快照讀,然后update、insert等,這時會用到當前讀,發(fā)現操作出現未預料結果。
幻讀解決方法
1、把事務隔離級別調整到SERIALIZABLE。2、RR隔離級別下,對select操作手動加行鎖,select ... for update,這也序列化隔離級別下隱式會做的事。
參考文章
事務隔離級別命令行操作
1、查看隔離級別
1)查看當前會話隔離級別
mysql> SELECT @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set, 1 warning (0.00 sec)
2)查看系統(tǒng)隔離級別
mysql> select @@global.tx_isolation; +-----------------------+ | @@global.tx_isolation | +-----------------------+ | READ-UNCOMMITTED | +-----------------------+ 1 row in set, 1 warning (0.00 sec)
2、設置隔離級別
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
1)設置當前會話
mysql> set session transaction isolation level repeatable read; Query OK, 0 rows affected (0.00 sec)
2)設置系統(tǒng)
mysql> set global transaction isolation level read uncommitted; Query OK, 0 rows affected (0.00 sec)3、命令行,開始事務時用
操作驗證
自己在命令行去驗證幾種隔離級別下的讀問題。
一、實現臟讀
在不可提交讀, 也就是READ UNCOMMITED情況下,會產生臟讀。

二、操作驗證--實現不可重復讀
在可提交讀, 也就是READ COMMITED情況下,會產生不可重復讀。

三、操作驗證--解決不可重復讀
repeatable read(MySQL默認隔離級別),這時候能解決可重復讀。
右邊事務提交了,修改了age=29,左邊再次查詢,還是28。

四、操作驗證--實現幻讀
repeatable read(MySQL默認隔離級別),這時候還會出現幻讀。

總結
到此這篇關于mysql數據庫隔離級別文章就介紹到這了,更多相關mysql隔離級別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
percona-toolkit之pt-kill 殺掉mysql查詢或連接的方法
本文主要描述了percona-toolkit中pt-kill的 使用實例 ,及 一些重要參數的介紹,需要的朋友可以參考下2016-04-04

