1.SELECT … FROM
是一个快照读,通过读取数据库的一个快照,不会加任何锁,除非将隔离级别设置成了 SERIALIZABLE 。
2.SELECT … FROM … LOCK IN SHARE MODE
在所有索引扫描范围的索引记录上加上共享的next key锁;如果是唯一索引,只需要在相应记录上加index record lock。这些被共享lock住的行无法进行update/delete。
允许其它事务对这些记录再加SHARE锁
如果没有使用到索引,则锁住全表(表级的排他锁),无法进行insert/update/delete。
3.SELECT … FROM … FOR UPDATE
在所有索引扫描范围的索引记录上加上排他的next key锁。如果是唯一索引,只需要在相应记录上加index record lock。
如果没有利用到索引将锁住全表(表级的排他锁),其它事务无法进行insert/update/delete操作。
- UPDATE … WHERE …
在所有索引扫描范围的索引记录上加上排他的next key锁。如果是唯一索引,只需要在相应记录上加index record lock。
如果没有利用到索引将锁住全表(表级的排他锁),其它事务无法进行其他的insert/update/delete操作。;
- DELETE FROM … WHERE …
语句在所有索引扫描范围的索引记录上加上排他的next key锁。如果是唯一索引,只需要在相应记录上加index record lock。
如果没有利用到索引将锁住全表(表级的排他锁),其它事务无法进行其它的insert/update/delete操作。
- INSERT
在插入的记录上加一把排他锁,这个锁是一个index-record lock,并不是next-key 锁,因此就没有gap 锁,他将不会阻止其他会话在该条记录之前的gap插入记录。
for update (将所有查询到的数据加上排它锁)
show status like 'innodb_row_lock%'; 展示行锁参数
优化建议:
1.尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
2.合理设计索引,尽量缩小锁的范围
3.尽可能较少检索条件,避免间隙锁
4.尽量控制事务大小,减少锁定资源量和时间长度
5.尽可能低级别事务隔离