未提交讀mysql
讀未提交,即可以讀取到沒有被提交的數據,因此很明顯這個級別的隔離機制沒法解決髒讀、不可重複讀、幻讀中的任何一種。
複製代碼
已提交讀sql
讀已提交,即可以讀到那些已經提交的數據,天然可以防止髒讀,可是沒法限制不可重複讀和幻讀
複製代碼
可重複讀數據庫
可重複讀,讀取了一條數據,這個事務不結束,別的事務就不能夠改這條記錄,這樣就解決了髒讀、不可重複讀的問題,
複製代碼
串行化markdown
串行化,多個事務時,只有運行完一個事務以後,才能運行其餘事務。
複製代碼
mysql默認的事務隔離級別爲repeatable-read併發
命令:oop
mysql -uroot -p 進入mysql
show databases 展現本地全部的數據庫
複製代碼
命令:性能
use test 選擇使用哪一個數據庫
show tables 顯示當前數據庫下全部的表
複製代碼
(1)打開一個客戶端A,並設置當前事務模式爲read uncommitted(未提交讀),查詢表user的初始值:
複製代碼
(2)在客戶端A的事務提交以前,打開另外一個客戶端B,更新表user:
複製代碼
(3)這時,雖然客戶端B的事務還沒提交,可是客戶端A就能夠查詢到B已經更新的數據:
複製代碼
(4)一旦客戶端B的事務由於某種緣由回滾,全部的操做都將會被撤銷,那客戶端A查詢到的數據其實就是髒數據:
複製代碼
(5)在客戶端A執行更新語句update user set money = money - 50 where id =1,男一的money沒有變成1940,竟然是1950,是否是很奇怪,數據不一致啊,若是你這麼想就太天真 了,在應用程序中,2000-50=1950,並不知道其餘會話回滾了,要想解決這個問題能夠採用讀已提交的隔離級別
複製代碼
(1)打開一個客戶端A,並設置當前事務模式爲read committed(未提交讀),查詢表user的全部記錄:
複製代碼
(2)在客戶端A的事務提交以前,打開另外一個客戶端B,更新表user:
複製代碼
(3)這時,客戶端B的事務還沒提交,客戶端A不能查詢到B已經更新的數據,解決了髒讀問題:
複製代碼
(4)客戶端B的事務提交
複製代碼
(5)客戶端A執行與上一步相同的查詢,結果 與上一步不一致,即產生了不可重複讀的問題
複製代碼
(1)打開一個客戶端A,並設置當前事務模式爲repeatable read,查詢表account的全部記錄
複製代碼
(2)在客戶端A的事務提交以前,打開另外一個客戶端B,更新表user並提交
複製代碼
(3)在客戶端A查詢表user的全部記錄,與步驟(1)查詢結果一致,沒有出現不可重複讀的問題
複製代碼
(4)在客戶端A,接着執行update user = money - 10 where id = 1,money沒有變成1990-10=1980,男一的money值用的是步驟(2)中的1980來算的,因此是1970,數據的一致性卻是沒有被破壞。可重複讀的隔離級別下使用了MVCC機制,select操做不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號,是當前讀(當前版本)。
複製代碼
(5)從新打開客戶端B,插入一條新數據後提交
複製代碼
(6)在客戶端A查詢表user的全部記錄,沒有 查出 新增數據,因此沒有出現幻讀
複製代碼
(1)打開一個客戶端A,並設置當前事務模式爲serializable,查詢表user的初始值:
2)打開一個客戶端B,並設置當前事務模式爲serializable,插入一條記錄報錯,表被鎖了插入失敗,mysql中事務隔離級別爲serializable時會鎖表,所以不會出現幻讀的狀況,這種隔離級別併發性極低,開發中不多會用到。
複製代碼
補充:spa
一、事務隔離級別爲讀提交時,寫數據只會鎖住相應的行.net
2 、事務隔離級別爲可重複讀時,若是檢索條件有索引(包括主鍵索引)的時候,默認加鎖方式是next-key 鎖;若是檢索條件沒有索引,更新數據時會鎖住整張表。一個間隙被事務加了鎖,其餘事務是不能在這個間隙插入記錄的,這樣能夠防止幻讀。命令行
三、事務隔離級別爲串行化時,讀寫數據都會鎖住整張表
4 、隔離級別越高,越能保證數據的完整性和一致性,可是對併發性能的影響也越大。
五、MYSQL MVCC實現機制參考連接:blog.csdn.net/whoamiyang/…
六、關於next-key 鎖能夠參考連接:blog.csdn.net/bigtree_372…