當前讀
需要加鎖,select * for unpdate 等
快照讀讀取的是快照,不需要加鎖,其他事物對此快照記憶體不受影響,其實得力於mvcc的版本控制
對於乙個mysql資料庫(innodb),事務的開啟與提交模式無非下面這兩種情況:
當前讀,讀取的是最新版本,並且對讀取的記錄加鎖,阻塞其他事務同時改動相同記錄,避免出現安全問題。
1.1哪些形式的sql屬於當前讀:
例如,假設要update一條記錄,但是另乙個事務已經delete這條資料並且commit了,如果不加鎖就會產生衝突。
所以update的時候肯定要是當前讀,得到最新的資訊並且鎖定相應的記錄。
關於for update
利用select * for update 可以鎖表/鎖行。
自然鎖表的壓力遠大於鎖行。所以我們應盡量採用鎖行。
for update僅適用於innodb,且必須在事務處理模組(begin/commit)中才能生效
那麼什麼時候鎖表呢?
1.2當前讀的實現方式
當前讀使用next-key鎖(行記錄鎖+gap間隙鎖)實現
間隙鎖
:只有在read repeatable、serializable隔離級別才有,就是鎖定範圍空間的資料,假設id有3,4,5,鎖定id>3的資料,是指的4,5及後面的數字都會被鎖定,因為此時如果不鎖定沒有的資料,例如當加入了新的資料id=6,就會出現幻讀,間隙鎖避免了幻讀。
單純的select操作,不包括上述 select ... lock in share mode, select ... for update。
read committed隔離級別:每次select都生成乙個快照讀
read repeatable隔離級別:開啟事務後第乙個select語句才是快照讀的地方,而不是一開啟事務就快照讀
快照讀的實現方式:undolog和多版本併發控制mvcc
下圖右側綠色的是資料:一行資料記錄,主鍵id是10,name='jack',age=10, 被update更新set為name= 'tom',age=23。
事務會先使用「排他鎖」鎖定該行,將該行當前的值複製到undo log中,然後再真正地修改當前行的值,最後填寫事務的db_trx_id,使用回滾指標db_roll_ptr指向undo log中修改前的行db_row_id。
MVCC快照讀 事務隔離級別 當前讀
mvcc快照讀 通過資料版本使資料庫的事務讀寫不用加鎖就可以保證事務的一致性 事務隔離級別 提交讀和可重複讀的事務隔離級別作用的資料範圍則分別對應不同的快照版本範圍 通過以上兩種機制的結合實現innodb事務下的高併發性。注 本來只有串讀隔離級別才可以解決幻讀問題,而實際上由於快照讀的特性使可重複讀...
mysql 快照讀和當前讀
以下都是在可重複讀隔離級別情況下的 快照讀 普通的不加鎖的select就是快照讀。通過readview實現,可重複讀級別時,整個事務的普通select都是使用同乙個readview。readview相關請看文章 總之,可以理解為當前事務建立後,會立即生成乙個快照,查詢的結果都是基於這個快照。新的其他...
Mysql快照讀和當前讀
讀取的是記錄資料的可見版本 可能是過期的資料 不用加鎖 讀取的是記錄資料的最新版本,並且當前讀返回的記錄都會加上鎖,保證其他事務不會再併發的修改這條記錄 概念說的比較虛,也不好理解,接著舉乙個例子吧,假設你開啟了兩個事務,分別是a和b,這裡有個張表,user表,裡面有四條資料 x表示是排它鎖 exc...