【问题标题】:Repeatable read mysql可重复读取mysql
【发布时间】:2018-12-06 08:43:04
【问题描述】:

在默认可重复读隔离级别的Mysql中,

在会话 1 事务 1 中,

start transaction;    
update student_details set name='uuu' where dept='mech';

已成功进行更改。此处列“dept”已编入索引。

在会话 2 事务 2 之后,

start transaction;
update student_details set name='kkk' where dept='ece';

此处也已成功进行更改。

但如果我在不索引“dept”列的情况下执行相同操作,则会话 2 中的事务 2 会一直等待,直到会话 1 中的事务 1 提交或回滚。

我知道,在可重复的读取隔离级别下,当我们执行“更新...where...”语句时,正在读取的每一行都被排他锁(写锁)锁定。因此事务 2 等待直到 1 释放它的锁。

那么,当我们索引一列并进行“更新...在哪里..”查询时,究竟会发生什么?为什么索引没有发生同样的事情??

【问题讨论】:

    标签: mysql isolation-level


    【解决方案1】:

    锁定读取(选择更新)、UPDATE 或 DELETE 通常会在 SQL 语句处理过程中扫描的每条索引记录上设置记录锁。语句中是否存在将排除该行的 WHERE 条件并不重要。 InnoDB 不记得确切的 WHERE 条件,而只知道扫描了哪些索引范围。锁通常是下一个键锁,它也阻止插入到记录之前的“间隙”中。

    正如MySQL 文档所述。

    意义,

    如果有索引,它会记住索引,因此row level locking happens

    如果找不到索引,则可能会出现lock on secondary indexesfull table locking 范围。

    因此,在您使用索引的情况下,会发生行级锁定,第二个事务可能会继续。 但是在没有索引的情况下,它会锁定其他事务。因此需要等待。

    【讨论】:

    • @Meenakshisundaram 如果它回答了你的问题,你能接受吗
    猜你喜欢
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    相关资源
    最近更新 更多