您好,登錄后才能下訂單哦!
如何理解MySQL的一致性讀,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
一 前言
MySQL 在不同的事務隔離級別下提供兩種讀模式 一致性讀(非加鎖), 當前讀(加鎖讀)。當前讀比較簡單,小編主要研究一致性讀取。
二 原理概念
官方概念
"A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. The query sees the changes made by transactions that committed before that point of time, and no changes made by later or uncommitted transactions.The exception to this rule is that the query sees the changes made by earlier statements within the same transaction. "
一致性讀是指使用MVCC機制讀取到某個事務已經提交的數據,其實是從undo里面獲取的數據快照。不過也有特例: 在本事務內如果修改某個表之后的select 可以讀取到該表最新的數據,后面的例子可以驗證。
三 不同事務隔離級別的一致性讀
3.1 RR模式
從官方文檔 "If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction."
在RR模式下,同一個事務內的一致性讀的快照都是基于第一次讀取操作時所建立的。下面我們做測試進行對RR模式下一致性讀進行解讀。
a)RR模式下事務的起始點是以執行的第一條語句為起始點的,而不是以begin作為事務的起始點的。
session 1 | session2 test [RW] 10:01:33 >begin; Query OK, 0 rows affected (0.00 sec) | test [RW] 10:02:12 >begin; Query OK, 0 rows affected (0.00 sec) |
test [RW] 10:02:22 >select * from ty; Empty set (0.00 sec) test [RW] 10:02:36 >insert into ty(a,b) values(1,2); Query OK, 1 row affected (0.00 sec) test [RW] 10:02:51 >commit; Query OK, 0 rows affected (0.00 sec) | ||
test [RW] 10:02:33 >select * from ty; +----+------+------+ | id | a |
b)RR模式下的一致性讀,是以第一條select語句的執行時間點作為snapshot建立的時間點的,即使是訪問不同的表。
test [RW] 10:35:11 >begin; Query OK, 0 rows affected (0.00 sec) test [RW] 10:35:13 >select * from x; +----+ | id | +----+ | test [RW] 10:34:32 >begin; Query OK, 0 rows affected (0.00 sec) | |
test [RW] 10:34:51 >insert into ty(a,b) values(2,4); Query OK, 1 row affected (0.00 sec) | |
test [RW] 10:35:39 >select * from ty; +----+------+------+ | id | a |
c)RR模式下,在本事務內如果修改某個表之后的對該表的select語句可以讀取到該表最新的數據。
test [RW] 10:42:56 >begin; Query OK, 0 rows affected (0.00 sec) test [RW] 10:43:07 >select * from ty; +----+------+------+ | id | a test [RW] 10:35:34 >begin; Query OK, 0 rows affected (0.00 sec) test [RW] 10:43:25 >insert into ty(a,b) values(3,5); Query OK, 1 row affected (0.00 sec) | |
test [RW] 10:43:38 >select * from ty; +----+------+------+ | id | a test [RW] 10:43:14 >update |
d)RR模式下同一個事務內,第一次查詢是當前讀操作則后續查詢可以查看最新的數據。
test [RW] 11:07:23 >begin;
Query OK, 0 rows affected (0.00 sec)
test [RW] 11:07:26 >update ty set a=5 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1
test [RW] 11:07:31 >begin;
Query OK, 0 rows affected (0.00 sec)
test [RW] 11:07:33 >select * from ty where id=2 for update;
+----+------+------+
| id | a
test [RW] 11:07:36 >insert into ty(a,b) values(6,7);
Query OK, 1 row affected (0.00 sec)
test [RW] 11:07:55 >commit;
Query OK, 0 rows affected (0.00 sec)
test [RW] 11:07:58 >select * from ty;
+----+------+------+
| id | a
With READ COMMITTED isolation level, each consistent read within a transaction sets and reads its own fresh snapshot.
四 當前讀
和一致性讀不太一樣 ,當前讀需要使用select xx for update,或者 lock in share mode ,讀取最新的數據并且鎖定被訪問的行,(RC 加行鎖,RR加gap鎖 唯一鍵除外) 不管另外一個事務是否提交,如果另外的事務已經獲取了相關的鎖,則 for update,lock in share mode 語句則繼續等待直到其他事務釋放鎖,并且獲取到最新的數據。
從上面的測試來看,RR模式下的一致性快照讀會有比較多的特性(姑且叫做特性吧) 。RC模式本身支持不可重復讀,能夠查詢到最新的其他事務最新提交的數據。基于上面的測試,還是比較推薦業務使用RC模式作為事務隔離級別的。
關于如何理解MySQL的一致性讀問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。