【问题标题】:Mysql repeatable read get other session's commit when use select ...for update使用 select ...for update 时,Mysql 可重复读取获取其他会话的提交
【发布时间】:2017-08-08 03:31:18
【问题描述】:

我的表的定义是

创建表auto_inc (

id int(11) NOT NULL AUTO_INCREMENT,

主键 (id)

) ENGINE=InnoDB 默认字符集=latin1

一开始有四行:

|身份证|

| 1 |

| 2 |

| 3 |

| 4 |

我打开了会话 1 并执行了

#session 1
set transaction isolation level REPEATABLE READ
start transaction;
select * from auto_inc

返回四行1,2,3,4。然后我打开另一个会话2并执行

#session 2
insert into auto_inc(`id`) values(null)

并插入成功。返回我执行的会话 1

#session 1
select * from auto_inc;#command 1
select * from auto_inc for update;#command 2

命令 1 返回四行 1,2,3,4。但是命令 2 返回 1,2,3,4,5。谁能给我一些线索,为什么命令 2 会看到会话 2 的插入? 提前致谢!

【问题讨论】:

  • 因为“撤消区域”不允许共享锁定。因此,命令 2 检索新数据,忽略导致“幻读”的快照。

标签: mysql isolation-level


【解决方案1】:
  1. 为什么会话 2 可以插入新数据?

在 REPEATABLE READ 下,第二个 SELECT 保证看到第一次选择时看到的行没有变化。并发事务可以添加新行,但不能删除或更改现有行。

https://stackoverflow.com/a/4036063/3020810

  1. 为什么session 1可以看到插入?

在 REPEATABLE READ 下,同一事务中的一致读取读取由第一次读取建立的快照。如果您想查看数据库的“最新”状态,请使用 READ COMMITTED 隔离级别或锁定读取,以及select ... for update 是锁定读取。

一致的非锁定读取:https://dev.mysql.com/doc/refman/5.6/en/innodb-consistent-read.html

【讨论】:

    猜你喜欢
    • 2016-02-20
    • 2014-03-10
    • 2018-06-16
    • 2020-04-04
    • 2017-10-03
    • 1970-01-01
    • 2018-02-24
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多