update delete 操作,如果走的索引,对索引和主键索引加行锁
如果没有走索引,锁整张表。
不开启事务,mysql本身也会加锁
一般MYSQL在执行CREATE,ALTER,INSERT等命令时会自动加锁
在对数据进行更新操作时
如果update没用到索引,直接锁表,不会死锁
如果update用到了索引,根据索引查询顺序进行索引加锁。因此可能会加锁顺序不一致导致死锁。
select语句会加读锁 (共享锁),只能读,不能对这条数据更新删除
间隙锁
select语句如果是范围查询,会锁住这一段范围共享读锁,对这个区间加锁,成为间隙锁。
解决办法:
1、禁用index_merge
在查询的时候只会走一个索引,不会都走。如果不禁用index_merge。会先走id1索引,再走id2索引,将查询结果求交集。
把两个索引设置成联合索引
先使用select查询出要更新的数据主键,再根据主键进行更新。
select * from t where d=5 for update,触发了什么锁?
可重复读隔离级别下:由于d没有索引,因此实际上是加入表锁,InnoDB的表锁形式为next-key lock(主键行锁+间隙锁),即会给数据库中的记录都加上行锁,还同时加上n+个间隙锁(n为已有记录数)。确保无法再插入新的记录。在一行行扫描的过程中,不仅将给行加上了行锁,还给行两边的空隙也加上间隙锁。间隙锁和行锁合称next-key lock,每个next-key lock是前开后闭区间。我们的表t初始化以后,如果用select * from t for update要把整个表所有记录锁起来,就形成了7个next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]。
读已提交下:语句执行完后,只有符合d=5的行会有行锁
来源地址:https://blog.csdn.net/weixin_44857939/article/details/129163184