使用 select ...for update 时,Mysql 可重复读取获取其他会话的提交
Posted
技术标签:
【中文标题】使用 select ...for update 时,Mysql 可重复读取获取其他会话的提交【英文标题】:Mysql repeatable read get other session's commit when use select ...for update 【发布时间】: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 检索新数据,忽略导致“幻读”的快照。 【参考方案1】:-
为什么会话 2 可以插入新数据?
在 REPEATABLE READ 下,第二个 SELECT 保证看到第一次选择时看到的行没有变化。并发事务可以添加新行,但不能删除或更改现有行。
https://***.com/a/4036063/3020810
-
为什么session 1可以看到插入?
在 REPEATABLE READ 下,同一事务中的一致读取读取由第一次读取建立的快照。如果您想查看数据库的“最新”状态,请使用 READ COMMITTED 隔离级别或锁定读取,以及select ... for update 是锁定读取。
一致的非锁定读取:https://dev.mysql.com/doc/refman/5.6/en/innodb-consistent-read.html
【讨论】:
以上是关于使用 select ...for update 时,Mysql 可重复读取获取其他会话的提交的主要内容,如果未能解决你的问题,请参考以下文章
Oracle编辑数据时提示:这些查询结果不可更新,请使用ROWI或者SELECT……FOR UPDATE获得可更新结果