讀取的是記錄資料的可見版本(可能是過期的資料),不用加鎖
讀取的是記錄資料的最新版本,並且當前讀返回的記錄都會加上鎖,保證其他事務不會再併發的修改這條記錄
概念說的比較虛,也不好理解,接著舉乙個例子吧,假設你開啟了兩個事務,分別是a和b,這裡有個張表,user表,裡面有四條資料
x表示是排它鎖(exclusive),s表示共享鎖(share),
1、select快照讀(**)
當你執行select *之後,在a與b事務中都會返回4條一樣的資料,這是不用想的,當執行select的時候,innodb缺省會執行快照讀,相當於就是給你目前的狀態找了一張**,以後執行select 的時候就會返回當前**裡面的資料,當其他事務提交了也對你不造成影響,和你沒關係,這就實現了可重複讀了,那這個**是什麼時候生成的呢?不是開啟事務的時候,是當你第一次執行select的時候,也就是說,當a開啟了事務,然後沒有執行任何操作,這時候b insert了一條資料然後commit,這時候a執行 select,那麼返回的資料中就會有b新增的那條資料......之後無論再有其他事務commit都沒有關係,因為**已經生成了,而且不會再生成了,以後都會參考這張**。
2、update、insert、delete 當前讀
當你執行這幾個操作的時候缺省會執行當前讀,也就是會讀取最新的記錄,也就是別的事務提交的資料你也可以看到,這樣很好理解啊,假設你要update乙個記錄,另乙個事務已經delete這條資料並且commit了,這樣不是會產生衝突嗎,所以你update的時候肯定要知道最新的資訊啊。
我在這裡介紹一下update的過程吧,首先會執行當前讀,然後把返回的資料加鎖,之後執行update。加鎖是防止別的事務在這個時候對這條記錄做什麼,預設加的是排他鎖,也就是你讀都不可以,這樣就可以保證資料不會出錯了。但注意一點,就算你這裡加了寫鎖,別的事務也還是能訪問的,是不是很奇怪?資料庫採取了一致性非鎖定讀,別的事務會去讀取乙個快照資料。
innodb預設隔離級別是rr, 是通過mvvc來實現了,讀方式有兩種,執行select的時候是快照讀,其餘是當前讀,所以,mvvc不能根本上解決幻讀的情況
mysql 快照讀和當前讀
以下都是在可重複讀隔離級別情況下的 快照讀 普通的不加鎖的select就是快照讀。通過readview實現,可重複讀級別時,整個事務的普通select都是使用同乙個readview。readview相關請看文章 總之,可以理解為當前事務建立後,會立即生成乙個快照,查詢的結果都是基於這個快照。新的其他...
MySql快照讀和當前讀
顧名思義,就是從當前狀態複製乙份快照出來,之後可以從快照裡讀取資料,但是並不是真正將整份資料複製的,而是利用了版本機制實現。簡單 select 不加鎖的語句就是快照讀。select from t user select from t user where id 1 全程在最新版本裡讀取資料。加鎖的 ...
當前讀和快照讀
在mvcc併發控制中,讀操作可以分成兩類 快照讀 snapshot read 與當前讀 current read 快照讀,讀取的是記錄的可見版本 有可能是歷史版本 不用加鎖。當前讀,讀取的是記錄的最新版本,並且,當前讀返回的記錄,都會加上鎖,保證其他事務不會再併發修改這條記錄。innodb的預設事務...