在《高效能mysql》一書中,是這樣描述的
根據書上的描述,mysql的可重複讀隔離級別通過mvcc
機制,解決了幻讀的問題,所以不會造成幻讀
本文預設你已經知道以下的命令
1. 查詢當前會話隔離級別
select @@tx_isolation
;
2. 設定當前會話隔離級別
set
session
transaction
isolation
level
repeatable
read
;
3. 查詢正在進行中的事務
select
*from information_schema.innodb_trx
準備實驗的表和資料
create
table
`user`(
`id`
int(11)
notnull
auto_increment
,`name`
varchar(30
)default
null
,`age`
tinyint(4
)default
null
,primary
key(
`id`))
;insert
into
user
values(1
,'張三',1
);
測試表資料如下:
開啟兩個會話視窗,分別都設定隔離級別為rr
按照順序執行以下操作
事務a事務b
①start transaction
—
②select * from user
—
—③start transaction
—④insert into user values(2,'李四',1)
—⑤commit
⑥select * from user
—
⑦update user set age = 2
—
⑧select * from user
—
按照上圖序號標註的順序,從①到⑥,在⑥查詢的時候,發現確實是沒有查到b事務新增的資料的,所以確實沒有幻讀。但是再執行⑦、⑧,會發現在⑧的時候,出現了幻讀
這裡預設你已經知道了mvcc
的原理,可以參考這篇文章mysql mvcc實現原理
簡單來說,就是mysql會預設給表增加兩個字段,乙個是標記建立時間,乙個標記過期時間(也是刪除時間),這裡的時間指的是當前事務的id
select
innodb會根據以下兩個條件檢查每行記錄:
只有符合上述兩個條件的記錄,才能返回作為查詢結果
insert
innodb為新插入的每一行儲存當前系統版本號作為行版本號。
delete
innodb為刪除的每一行儲存當前系統版本號作為行刪除標識。
update
innodb為插入一行新記錄,儲存當前系統版本號作為行版本號,同時儲存當前系統版本號到原來的行作為行刪除標識。
帶上這兩個字段,分析下測試資料
執行完②
idname
age建立時間
刪除時間1張三
11執行完⑤
idname
age建立時間
刪除時間1張三
112李四
12執行⑥的時候,根據select
的時候版本號規則,查詢小於等於當前版本號,所以只能查出id = 1
的資料,沒有幻讀
執行完⑦
idname
age建立時間
刪除時間1張三
112李四
1212
李四11根據update
的版本號規則,現在資料庫應該有三條資料
所以再執行⑧的查詢,根據select
的查詢規則,應該是能看到新增的資料,產生了幻讀
所以我認為mysql的mvcc
機制並沒有完全解決幻讀問題。
這是我自己的理解,如果有誤還請指出
mysql 可重複讀。
一 可重複讀 我們先看看現象,再分析原理。我的mysql版本是5.5。下面是一張表,只有一條資料,並且我開啟了事物 此時,另乙個事物將record加1,因此我在開啟乙個命令列客戶端,執行下面的命令 成功加1之後,實際上,資料庫中record肯定是2。然後回到之前的客戶端,再查一次 沒毛病,recor...
mysql可重複讀
mysql innodb的預設隔離級別是可重複讀,之前理解有些偏差,查閱一些資料後總結出幾點 首先有兩個概念 一致性檢視 當乙個事務開啟時,innodb會生成乙個檢視,這個檢視是邏輯檢視,通過undo log和row tranzaction id控制實現。在該事務的任何時間點,一致性檢視中的資料都是...
MySQL事務隔離級別可重複讀測試
開啟rds,查詢當前的事務隔離級別select tx isolation查詢得到時候可重複讀,於是做了如下測試。可重複隔離級別的特點是,每個事務可以在乙個事務中可以反覆讀取資料,每次讀取到的資料都是相同的。在 高效能mysql 一書中,講到這種隔離級別很好的解決了髒讀問題,也就是讀取的資料都是事務開...