參考資料:
mysql innodb鎖介紹及不同sql語句分別加什麼樣的鎖
innodb鎖機制
mysql 一致性讀 深入研究
極客時間課程:mysql實戰45講
隔離級別總覽:下面主要講述rc和rr兩個級別
隔離性正是通過鎖機制來實現的。提到鎖就會涉及到死鎖,需要明確的是死鎖的可能性並不受隔離級別的影響,因為隔離級別改變的是讀操作的行為,而死鎖是由於寫操作產生的。
innodb採用多版本併發控制(mvcc, multiversion concurrency control)來增加讀操作的併發性。mvcc是指,innodb使用基於時間點的快照來獲取查詢結果,讀取時在訪問的表上不設定任何鎖,因此,在事務t1讀取的同一時刻,事務t2可以自由的修改事務t1所讀取的資料。這種讀操作被稱為一致性非鎖定讀。這裡的讀操作就是普通select。
innodb有兩種不同的select,即普通select 和 鎖定讀select。鎖定讀select 又有兩種,即select … for share 和 select … for update;鎖定讀select 之外的則是 普通select 。
普通select 時使用一致性非鎖定讀,不加鎖;
鎖定讀select 使用鎖定讀,加鎖;
隔離級別為ru和serializable時不需要mvcc,因此,只有rc和rr時,才存在mvcc,才存在一致性非鎖定讀。
transactionid:在開始乙個事務的時候生成乙個transactionid,更新插入的時候把這個id記到資料中
rc級別下:每一次select操作都會重新建立一致性檢視,重新生成乙個transactionid,在一些文章中這種叫做每次都取最新的數快照。所以會出現不可重複讀的情況。
rr級別下:只建立一次一致性檢視,所以不會出現不可重複讀的情況。
一致性檢視在第一次一致性讀select語句執行的時候建立。類似於show create table 這種操作是不會建立快照的。
從一致性檢視建立的時間來看資料是否可見。
1) 版本未提交,不可見;
2) 版本已提交,但是是在檢視建立後提交的,不可見;
3) 版本已提交,而且是在檢視建立前提交的,可見。
1)一致性檢視在第一次select語句的時候建立(例子為rr級別下的情況)
2)隔離級別改變的是讀操作行為,不影響更新操作(例子為rr級別下的情況)
更新操作總是取最新的記錄去更新操作。這裡其實就是出現了幻讀,明明select的時候不存在id=1的記錄,但是更新的時候又存在。
3)儲存資料的時候將當前transactionid儲存到資料記錄中(例子為rr級別下的情況)
原理猜測:update id=2的時候,會將當前transactionid儲存到資料記錄中,即事務1的id,按照圖一的變更鏈應該是如下情況。
對於id=2的記錄:[transaction=事務2,data]
對於id=1的記錄:[transaction=事務2,data]
當執行select id>0的時候,id=2的記錄是屬於當前事務更新的,所以可見,而id=1的記錄是事務2的更新結果,是不可見的。所以查不到。
事務隔離級別與髒讀 幻讀 不可重複讀
我們知道,事務的四大特性是a 原子性 c 一致性 i 隔離性 d 永續性 事務隔離級別就是為了滿足隔離性的機制。在併發場景下,如果沒有一定的處理方式,就會出現髒讀 幻讀 不可重複讀三類問題。髒讀 事務a在執行過程中,修改了某資料,事務b讀取了修改後的資料,然後事務a進行了回滾操作,這個時候事務b讀取...
事務隔離級別 髒讀 不可重複讀 幻讀 介紹
事務是現代關係型資料庫的核心之一。在多個事務併發運算元據庫 多執行緒 網路併發等 的時候,如果沒有有效的避免機制,就會出現以下幾種問題 a事務執行過程中,b事務讀取了a事務的修改。但是由於某些原因,a事務可能沒有完成提交,發生rollback了操作,則b事務所讀取的資料就會是不正確的。這個未提交資料...
髒讀 幻讀和不可重複讀 事務隔離級別
1.髒讀 髒讀就是指當乙個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外乙個事務也訪問這個資料,然後使用了這個資料。e.g.1.mary的原工資為1000,財務人員將mary的工資改為了8000 但未提交事務 2.mary讀取自己的工資 發現自己的工資變為了800...