可重复读取 mysql
Repeatable read mysql
在具有默认可重复读取隔离级别的 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 被提交或回滚。
我知道,在可重复读取隔离级别中,当我们进行 'update...where...' 语句时,正在读取的每一行都被独占锁(写锁)锁定。因此事务 2 等待直到 1 释放它的锁。
那么,当我们索引列并进行 'update...where..' 查询时,究竟发生了什么?为什么索引没有发生同样的事情??
A locking read(select for update), an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row. InnoDB does not remember the exact WHERE condition, but only knows which index ranges were scanned. The locks are normally next-key locks that also block inserts into the “gap” immediately before the record.
如 MySQL 文档所述。
意义,
如果有索引,它会记住索引,因此row level locking happens
。
如果找不到索引,则范围 lock on secondary indexes
或 full table locking
可能会发生。
因此在您使用索引的情况下,发生行级锁定,第二个事务可以继续。
但是如果没有索引,它会锁定其他事务。因此需要等待。
在具有默认可重复读取隔离级别的 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 被提交或回滚。
我知道,在可重复读取隔离级别中,当我们进行 'update...where...' 语句时,正在读取的每一行都被独占锁(写锁)锁定。因此事务 2 等待直到 1 释放它的锁。
那么,当我们索引列并进行 'update...where..' 查询时,究竟发生了什么?为什么索引没有发生同样的事情??
A locking read(select for update), an UPDATE, or a DELETE generally set record locks on every index record that is scanned in the processing of the SQL statement. It does not matter whether there are WHERE conditions in the statement that would exclude the row. InnoDB does not remember the exact WHERE condition, but only knows which index ranges were scanned. The locks are normally next-key locks that also block inserts into the “gap” immediately before the record.
如 MySQL 文档所述。
意义,
如果有索引,它会记住索引,因此row level locking happens
。
如果找不到索引,则范围 lock on secondary indexes
或 full table locking
可能会发生。
因此在您使用索引的情况下,发生行级锁定,第二个事务可以继续。 但是如果没有索引,它会锁定其他事务。因此需要等待。