如果同時(shí)開啟事務(wù) A 和事務(wù) B,且當(dāng)前事務(wù)隔離級(jí)別是可重復(fù)讀的時(shí)候,查詢和更新會(huì)有什么影響?
- 事務(wù) A 提交會(huì)不會(huì)影響事務(wù) B 查詢?
- 查看當(dāng)前會(huì)話的隔離級(jí)別。
SELECT @@tx_isolation
確認(rèn)環(huán)境 -
同時(shí)開啟兩個(gè)窗口,同時(shí)開啟事務(wù) A、B。
事務(wù)A

事務(wù)B
- 事務(wù) A 和 B 同時(shí)做查詢修改操作模擬。
事務(wù) A 修改數(shù)據(jù)并提交
事務(wù) B 查詢數(shù)據(jù),但是當(dāng)前數(shù)據(jù)并沒有提交
在這里可以看到,事務(wù) A 修改數(shù)據(jù)提交了,但是事務(wù) B 仍在事務(wù)中,并沒有 COMMIT , 查詢到的數(shù)據(jù)id=5的name值仍然是‘333’,讀取的仍然是事務(wù) A 提交之前的數(shù)據(jù)
- 事務(wù) A 修改的數(shù)據(jù),事務(wù) B 里能影響到嗎?
- 上面運(yùn)行結(jié)果可以看到,事務(wù) A 做了數(shù)據(jù)的
update,此時(shí)事務(wù) B 還在SELECT中,但是沒有COMMIT,此時(shí)查詢的數(shù)據(jù)仍是原始數(shù)據(jù),并沒有查詢到事務(wù) A 中更新的數(shù)據(jù)信息。 - 嘗試在事務(wù) B 中更新數(shù)據(jù),但是用事務(wù) A 中已經(jīng)更新的數(shù)據(jù)做 WHERE 條件過濾
注意看條件是 where id = 5 and name = 555
這里注意的是name = 555是事務(wù) A 執(zhí)行的,事務(wù) B 此時(shí)并查詢不到name=555的最新數(shù)據(jù)。講道理這里是更新不上的,因?yàn)闆]有name = 555此條記錄,但是執(zhí)行結(jié)果是Rows matched 1。 更新上了。再次查詢的結(jié)果name=555 & email=555@qq.com, 已經(jīng)可以用事務(wù) A 的更新結(jié)果做條件查詢了。
- 總結(jié)?:
- 僅僅使用
SELECT語句的時(shí)候,臟讀并不會(huì)發(fā)生,因?yàn)樵谑聞?wù) A 修改數(shù)據(jù)并 COMMIT 之后, 事務(wù) B 中查詢到的數(shù)據(jù)信息仍是剛開始的數(shù)據(jù)記錄。 - 但是對(duì)數(shù)據(jù)進(jìn)行修改的時(shí)候,則表現(xiàn)出來的行為混合了可重復(fù)讀(沒有修改的行是可見的)和讀已提交(修改的行是可見的)
在例子中表示的是 name == 555,這個(gè)條件是事務(wù) A 提交的,事務(wù) B 中并沒有查詢到,但是可以做 WHERE 條件子句。
還有嗎???
- 20211123 補(bǔ)充:
參考:https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
官網(wǎng)文檔給出的示例
可以看出此快照,作用于SELECT, 但是對(duì)DML語句不一定使用,也就是說,當(dāng)有更新、刪除等操作的時(shí)候,另外一個(gè)事務(wù)可以立刻看到。





