三種bug:
髒讀:
例:insert into T values (4, '牛D');
,然後沒commit。
其他進程SELECT
讀取到的數據是未commit的數據。(數據庫只修改了內存沒修改外存)
不可重複讀:
例:一個事務範圍內兩個相同的查詢卻返回了不同數據(因爲中間有進程修改了值並且提交成功)
幻讀:
例:某個事務在讀取某個範圍的數據,但是另一個事務又向這個範圍的數據去插入數據,導致多次讀取的時候,數據的行數不一致。
- READ UNCIMMITTED(未提交讀)
在這種隔離級別下,查詢是不會加鎖的,也由於查詢的不加鎖,所以這種隔離級別的一致性是最差的,可能會產生“髒讀”、“不可重複讀”、“幻讀”。
image.png
- READ COMMITTED(提交讀)
就是隻能讀到已經提交了的內容。
爲什麼提交讀,未提交讀都沒有查詢加鎖,但是卻能夠避免髒讀呢?
這就要說道另一個機制-快照(snapshot)
當B insert了一條數據然後commit,這時候A執行 select,那麼返回的數據中就會有B添加的那條數據......之後無論再有其他事務commit都沒有關係,因爲照片已經生成了,而且不會再生成了,以後都會參考這張照片。
-
假設沒有“快照讀”,那麼當一個更新的事務沒有提交時,另一個對更新數據進行查詢的事務會因爲無法查詢而被阻塞,這種情況下,併發能力就相當的差。
-
而“快照讀”就可以完成高併發的查詢,不過,“讀提交”只能避免
髒讀
,並不能避免“不可重複讀”(插入INSERT不是更新UPDATE)和“幻讀”。image.png
- REPEATABLE READ(可重複讀)
普通的查詢同樣是使用的“快照讀”,但是,和“讀提交”不同的是,當事務啓動時,就不允許進行“修改操作(Update)”了,而“不可重複讀”恰恰是因爲兩次讀取之間進行了數據的修改,因此,“可重複讀”能夠有效的避免不可重複讀
,但卻避免不了“幻讀”,因爲幻讀是由於“插入或者刪除操作(INSERT or DELETE)”而產生的,而不是更新(UPDATE)。
image.png
- SERIALIZABLE(可串行化)
這種級別下,事務“串行化順序執行”,也就是一個一個排隊執行。由於他大量加上鎖,導致大量的請求超時,因此性能會比較底下,再特別需要數據一致性且併發量不需要那麼大的時候纔可能考慮這個隔離級別。
image.png
作者:小幸運Q
鏈接:https://www.jianshu.com/p/9340b3daf20d
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。