有朋友留言,问能不能花2分钟讲讲MySQL的各种SQL语句加了什么样的锁?那么,MySQL加的锁是跟事务隔离级别有关,跟索引有关。尝试花2分钟。一会儿再说。画外音:这2分钟所需的辅助知识已附链接,请见谅!第一类,普通select加什么锁?(1)未提交读(ReadUncommitted)、已提交读(ReadCommitted,RC),可以在重复读(RepeatedRead,RR)三种事务隔离级别下,普通select使用快照读(snpashotread),不加锁,以及并发度很高;(2)在可序列化(Serializable)事务的隔离级别下,普通select将升级为share模式的select...;【快照阅读】辅助阅读:《??InnoDB,并发如此之高的原因??》第二类,lockedselect加什么锁?Lockedselect主要是指:select...forupdateselect。..在共享模式下(1)如果在唯一索引(uniqueindex)上使用唯一查询条件(uniquesearchcondition),会使用记录锁(recordlock),不会阻塞记录之间的间隔,即不将使用Gaplock和next-keylock;[recordlock,gaplock,next-keylock]辅助阅读:《??InnoDB里的七种锁??》比如假设有一张InnoDB表:t(idPK,name);表中有3条记录:shenjianzhangsanlisiSQL语句:select*fromtwhereid=1forupdate;只有记录会被阻塞,但间隔不会被阻塞。(2)对于其他查询条件和索引条件,InnoDB会阻塞扫描的索引范围,使用间隙锁和邻键锁避免在索引范围范围内插入记录;第三类,update和delete加什么锁?(1)类似于lockingselect,如果在唯一索引上使用唯一查询条件进行update/delete,例如:updatetsetname=xxxwhereid=1;仅添加记录锁;(2)否则,满足查询条件的索引在记录之前,会加一个排他next-key锁,阻塞索引记录和之前的区间;(3)特别说明,如果更新的是聚簇索引记录,对应的普通索引(二级索引)记录也会被隐式加锁,这是由InnoDB索引的实现机制决定的:普通索引存储的是值PK,而检索普通索引本质上需要对聚集索引进行二次扫描。【索引底层实现】补充阅读:《??索引,底层是如何实现的???》【聚集索引与普通索引的区别】补充阅读:《??InnoDB,聚集索引与普通索引有什么不同???》第四类,insert加什么锁?同样是写操作,insert和update不同于delete,它会用独占锁Block插入的索引记录,不会阻塞记录之前的范围。同时会在插入区间加一个插入意向锁,但这并不会真正阻塞区间,也不会阻止同一区间的不同KEY被插入。【插入意向锁】辅助阅读:《??InnoDB里的七种锁??》了解不同SQL语句的加锁,对于分析多事务之间的并发互斥,以及事务死锁等问题,都有很大的帮助。画外音:本文参考资料为MySQL官网,以及作者对MySQL的理解。该版本基于5.6。欢迎讨论。我希望这2分钟对每个人都有收获。来源链接:http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651969353&idx=1&sn=9ded4fe3fcfc9e3daf1ce52054671b4a&chksm=bd2d62958a5aeb835405358634ffea69936a6dd3941dd2a338401661c77393838879c043db69&mpshare=1&scene=23&srcid=0118Za6sAKYOr1w7CpQHHEMB&sharer_sharetime=1642517052262&sharer_shareid=9603544ecd5d7f3dc66603ae089636f4#rd
