什么是mysql的可重复读
今天就跟大家聊聊有關什么是mysql的可重復讀,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
引入問題
這個問題來源于一個網絡課程的課后思考題,題目是這樣的:
我用下面的表結構和初始化語句作為試驗環境,事務隔離級別是可重復讀?,F在,我要把所有“字段 c 和 id 值相等的行”的 c 值清零,但是卻發現了一
個“詭異”的、改不掉的情況。請你構造出這種情況,并說明其原理。
mysql>CREATETABLE`test2`(
`id`int(11)NOTNULL,
`c`int(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDB;
insertintotest2(id,c)values(1,1),(2,2),(3,3),(4,4);
補充解釋下這個問題,mysql環境,innodb引擎,事務的隔離級別是可重復讀,一個表只有兩個字段,然后插入4條數據,希望你構造上圖中的一種情況,就是明明update了,但是結果沒有更新,select也好像沒有生效。
給出問題的答案
先直接給出答案吧,
開啟兩個mysql的交互窗口,模擬兩個事物的操作,比如一個事物叫A,一個事物叫B。
流程是這樣的,
//事物A
starttransactionwithconsistentsnapshot;
//事物B
updatetest2setc=c+4;
//事物A
updatetest2setc=0whereid=c;
//事物A
select*fromtest2;
具體操作的截圖如下,
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的可重复读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodejs TCP server和TC
- 下一篇: SAP CRM里的settype和rel