当使用 select ...for update 时,Mysql 可重复读取获取其他 session 的提交

标签 mysql isolation-level

我的表的定义是

CREATE TABLE auto_inc (

id int(11) NOT NULL AUTO_INCREMENT,

PRIMARY KEY (id)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

一开始有四行:

| id |

| 1 |

| 2 |

| 3 |

| 4 |

我打开 session 1并执行

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

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

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

并插入成功。返回到我执行的 session 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 会看到 session 2 的插入吗? 提前致谢!

最佳答案

  1. 为什么 session 2可以插入新数据?

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

https://stackoverflow.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 可重复读取获取其他 session 的提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45558837/

    相关文章:

    oracle - 如何查看任意 oracle session 使用的事务隔离级别

    spring - Spring事务传播和隔离

    mysql - 如何使用 Play、Hibernate 和 MySql 设置每个 session 的事务隔离级别

    postgresql - 用于具有大量更新的长时间运行事务的数据库

    php - 如何在不使用多个查询语句的情况下将特定的 dbs 值分配给多个变量?

    php - 有没有一种方法可以仅通过使用notepad++和mysql服务器5.0来使用php和mysql?

    php - 按列分组并排除一个值

    mysql - 如何有效地将行值重新排列为数据库中的排序顺序?

    mysql - 多个消费者尝试更新 Mysql(5.7 版本)表的同一行。如何解决并发更新问题

    mysql - 查询以获取表中最接近的日期