在默认可重复读取隔离级别的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…”语句时,正在读取的每一行都被一个独占锁(write lock)锁定。因此事务2会等待,直到1释放它的锁。
那么,当我们索引一列并进行“update…where..”查询时,会发生什么呢?为什么索引没有发生同样的事情??
1条答案
按热度按时间r6l8ljro1#
锁定读取(select for update)、更新或删除通常会对sql语句处理过程中扫描的每个索引记录设置记录锁定。语句中是否存在排除该行的where条件并不重要。innodb不记得确切的where条件,只知道扫描了哪些索引范围。这些锁通常是下一个键锁,也会阻止插入到紧靠记录之前的“间隙”中。
如mysql文档所述。
意思是,
如果有索引,它会记住索引,因此
row level locking happens
.如果它找不到索引,那么
lock on secondary indexes
或者full table locking
可能发生。所以在使用索引的情况下,行级锁定发生,第二个事务可以继续进行。但在没有索引的情况下,它会锁定其他事务。因此需要等待。