别废话,各种SQL到底加了什么锁?

发表于:2022-1-24 09:10

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:KG沈剑    来源:架构师之路

#
SQL
分享:
  第一类,普通select加什么锁?
  (1)在读未提交(Read Uncommitted),读提交(Read Committed, RC),可重复读(Repeated Read, RR)这三种事务隔离级别下,普通select使用快照读(snpashot read),不加锁,并发非常高;
  (2)在串行化(Serializable)这种事务的隔离级别下,普通select会升级为select ... in share mode。
  第二类,加锁select加什么锁?
  加锁select主要是指:
  · select ... for update
  · select ... in share mode
  (1)如果,在唯一索引(unique index)上使用唯一的查询条件(unique search condition),会使用记录锁(record lock),而不会封锁记录之间的间隔,即不会使用间隙锁(gap lock)与临键锁(next-key lock);
  举个栗子,假设有InnoDB表:
  t(id PK, name);
  表中有三条记录:
  · shenjian
  · zhangsan
  · lisi
  SQL语句:
  select * from t where id=1 for update;
  只会封锁记录,而不会封锁区间。
  (2)其他的查询条件和索引条件,InnoDB会封锁被扫描的索引范围,并使用间隙锁与临键锁,避免索引范围区间插入记录。
  第三类,update与delete加什么锁?
  (1)和加锁select类似,如果在唯一索引上使用唯一的查询条件来update/delete,例如:update t set name=xxx where id=1;也只加记录锁;
  (2)否则,符合查询条件的索引记录之前,都会加排他临键锁(exclusive next-key lock),来封锁索引记录与之前的区间;
  (3)尤其需要特殊说明的是,如果update的是聚集索引(clustered index)记录,则对应的普通索引(secondary index)记录也会被隐式加锁,这是由InnoDB索引的实现机制决定的:普通索引存储PK的值,检索普通索引本质上要二次扫描聚集索引。
  第四类,insert加什么锁?
  同样是写操作,insert和update与delete不同,它会用排它锁封锁被插入的索引记录,而不会封锁记录之前的范围。
  同时,会在插入区间加插入意向锁(insert intention lock),但这个并不会真正封锁区间,也不会阻止相同区间的不同KEY插入。
  了解不同SQL语句的加锁,对于分析多个事务之间的并发与互斥,以及事务死锁,非常有帮助。
  画外音:文章的参考资料为MySQL官网,以及楼主对MySQL的理解,版本基于5.6,欢迎探讨。希望这2分钟,大家有收获。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号