在具有默认可重复读取隔离级别的Mysql中,
在会话1的交易1中,
start transaction;
update student_details set name='uuu' where dept='mech';
更改已成功完成。在这里,“部门”列已建立索引。
在会话2事务2中完成此操作
start transaction;
update student_details set name='kkk' where dept='ece';
这里也成功进行了更改。
但是,如果我没有对'dept'列建立索引就做同样的事情,那么会话2中的事务2将一直等待,直到会话1中的事务1被提交或回滚为止。
我知道,以可重复的读取隔离级别,当我们执行'update ... where ...'语句时,正在读取的每一行都被排他锁(write lock)锁定。因此事务2等待直到1释放其锁。
那么,当我们索引一列并进行“ update ... where ..”查询时,会发生什么呢?为什么索引不会发生相同的事情?
答案 0 :(得分:0)
锁定读取(选择更新),UPDATE或DELETE通常会对在处理SQL语句时扫描的每个索引记录设置记录锁定。语句中是否存在排除行的条件并不重要。 InnoDB不记得确切的WHERE条件,而只知道扫描了哪个索引范围。锁通常是下一键锁,也可以阻止紧接记录之前插入“间隙”中。
如状态MySQL文档所述。
含义
如果有索引,它将记住索引,因此为row level locking happens
。
如果找不到索引,则可能会发生范围lock on secondary indexes
或full table locking
。
因此,在您使用索引的情况下,发生行级锁定,第二个事务可能继续进行。 但是,如果没有索引,它将锁定其他事务。因此需要等待。