您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關什么是mysql的可重復讀,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
這個問題來源于一個網絡課程的課后思考題,題目是這樣的:
我用下面的表結構和初始化語句作為試驗環境,事務隔離級別是可重復讀。現在,我要把所有“字段 c 和 id 值相等的行”的 c 值清零,但是卻發現了一
個“詭異”的、改不掉的情況。請你構造出這種情況,并說明其原理。
mysql> CREATE TABLE `test2` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into test2(id, c) values(1,1),(2,2),(3,3),(4,4);
補充解釋下這個問題,mysql環境,innodb引擎,事務的隔離級別是可重復讀
,一個表只有兩個字段,然后插入4條數據,希望你構造上圖中的一種情況,就是明明update了,但是結果沒有更新,select也好像沒有生效。
先直接給出答案吧,
開啟兩個mysql的交互窗口,模擬兩個事物的操作,比如一個事物叫A,一個事物叫B。
流程是這樣的,
//事物A
start transaction with consistent snapshot;
//事物B
update test2 set c = c + 4;
//事物A
update test2 set c = 0 where id = c;
//事物A
select * from test2;
具體操作的截圖如下,
A事物 commit 后(事物結束),才可以通過select看到真實數據。
要理解這個問題的答案,首先需要搞懂什么是可重復讀的隔離級別。
可重復讀隔離級別,事務 A 啟動的時候會創建一個視圖 read-view,之后事務 A 執行期間,即使有其他事務修改了數據,事務 A 看到的仍然跟在啟動時看到的一樣。
我們首先在事物 A 執行 start transaction with consistent snapshot
,這個就開始了事物A的生命周期,并且是手動事物。因為 start transaction
默認就禁用了autocommit。
然后事物 B 開始直接執行了update。為了操作簡單這里用了自動事物。也就是事物 B 在update后事物就提交了。
這個時候數據變成了下面這個樣子:
id | c |
---|---|
1 | 5 |
2 | 6 |
3 | 7 |
4 | 8 |
然后事物A繼續執行 update test2 set c = 0 where id = c;
,很明顯由于事物B已經提交了,事物A的update的使用的是當前讀
,判斷條件不滿足,所以事物 A 不會更新任何數據。
接著,事物 A 執行select語句,為什么結果還是以前的數據呢?是因為事物 A 的select使用的一致讀
,也叫快照讀,讀取的還是以前的快照數據。
一致性讀是讀取在某個時間點已經提交了的數據, 在本示例中,這個時間點就是 start transaction with consistent snapshot
執行的時間點。
索引,現在互聯網公司大部分會把隔離級別設置成RC(Read Commited),也就是讀已提交模式。當然除了上面那個問題,還有其它原因,這個不是本文的重點就不展開來講了。
看完上述內容,你們對什么是mysql的可重復讀有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。