如果同时开启事务 A 和事务 B,且当前事务隔离级别是可重复读的时候,查询和更新会有什么影响?
- 事务 A 提交会不会影响事务 B 查询?
- 查看当前会话的隔离级别。
SELECT @@tx_isolation
确认环境 -
同时开启两个窗口,同时开启事务 A、B。
事务A
- 事务 A 和 B 同时做查询修改操作模拟。
事务 A 修改数据并提交
事务 B 查询数据,但是当前数据并没有提交
在这里可以看到,事务 A 修改数据提交了,但是事务 B 仍在事务中,并没有 COMMIT , 查询到的数据id=5
的name
值仍然是‘333’,读取的仍然是事务 A 提交之前的数据
- 事务 A 修改的数据,事务 B 里能影响到吗?
- 上面运行结果可以看到,事务 A 做了数据的
update
,此时事务 B 还在SELECT
中,但是没有COMMIT
,此时查询的数据仍是原始数据,并没有查询到事务 A 中更新的数据信息。 - 尝试在事务 B 中更新数据,但是用事务 A 中已经更新的数据做 WHERE 条件过滤
注意看条件是 where id = 5 and name = 555
这里注意的是name = 555
是事务 A 执行的,事务 B 此时并查询不到name=555
的最新数据。讲道理这里是更新不上的,因为没有name = 555
此条记录,但是执行结果是Rows matched 1
。 更新上了。再次查询的结果name=555 & email=555@qq.com
, 已经可以用事务 A 的更新结果做条件查询了。
- 总结?:
- 仅仅使用
SELECT
语句的时候,脏读并不会发生,因为在事务 A 修改数据并 COMMIT 之后, 事务 B 中查询到的数据信息仍是刚开始的数据记录。 - 但是对数据进行修改的时候,则表现出来的行为混合了可重复读(没有修改的行是可见的)和读已提交(修改的行是可见的)
在例子中表示的是 name == 555,这个条件是事务 A 提交的,事务 B 中并没有查询到,但是可以做 WHERE 条件子句
。
还有吗???
- 20211123 补充:
参考:https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
官网文档给出的示例
可以看出此快照,作用于SELECT
, 但是对DML
语句不一定使用,也就是说,当有更新、删除等操作的时候,另外一个事务可以立刻看到。
网友评论