mysql的锁

发布时间:2022-06-28 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了mysql的锁脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

锁的分类

  • 从性能上分为乐观锁(用版本对比来实现)和悲观锁
  • 从对数据库操作的类型分,分为读锁和写锁(都属于悲观锁)。
    • 读锁(共享锁,S锁(Shared)):针对同一份数据,多个读操作可以同时进行而不会互相影响
    • 写锁(排它锁,X锁(eXclusive)):当前写操作没有完成前,它会阻断其他写锁和读锁
  • 从对数据操作的粒度分,分为表锁和行锁

表锁与行锁

表锁

  • 每次操作锁住整张表。
  • 开销小(不需要定位到某个元素,只需要定位到表),加锁快;
  • 不会出现死锁;
  • 锁定粒度大,发生锁冲突的概率最高,并发度最低;
  • 一般用在整表数据迁移的场景。

表锁操作方式

  • 手动增加表锁: lock table 表名称 read(wrITe),表名称2 read(write);
  • 查看表上加过的锁 show oPEn tables;
  • 删除表锁 unlock tables;

行锁

  • 每次操作锁住一行数据。
  • 开销大,加锁慢;
  • 会出现死锁;
  • 锁定粒度最小,发生锁冲突的概率最低,并发度高。
  • InnoDB与MYISam的最大不同点:InnoDB支持行级锁、支持事务
  • MyISAM在执行查询语句SELECT前,会自动给涉及的所有表加读锁,在执行update、insert、delete操作会自动给涉及的表加写锁。
  • InnoDB在执行查询语句SELECT时(非串行隔离级别),不会加锁。但是update、insert、delete操作会加行锁。

行锁操作方式

  • SQL后增加for update来实现行锁。
  • for update在不走索引的时候会锁表!但是当要修改或者查询的数据不存在的时候,不会锁表,也不会锁定行!

读锁与写锁

  • 读锁会阻塞写,但是不会阻塞读。而写锁则会把读和写都阻塞。

乐观锁与悲观锁

乐观锁

  • 乐观锁时会假设在极大多数情况下不会形成冲突,只有在数据提交的时候,才会对数据是否产生冲突进行检验。发生冲突后,不修改数据

实现方式

  • 在数据库表中增加一列,记为version,当我们将数据读出时,将版本号一并读出,当数据进行更新时,会对这个版本号进行加1,当我们提交数据时,会判断数据库表中当前的version列值和当时读出的version是否相同,若相同说明没有进行更新的操作,不然,则取消这次的操作。

悲观锁

  • MySQL的悲观锁就是打开事务,当启动事务时,如果事务中的sql语句涉及到索引并用索引进行了条件判断,那么会使用行级锁锁定所要修改的行,否则使用表锁锁住整张表。

实现方式

  • sql后增加for update来实现悲观锁。
  • for update在不走索引的时候会锁表!
  • 当要修改或者查询的数据不存在的时候,不会锁表,也不会锁定行!

当InnoDB表有多个索引的时候,不同事务使用不同的索引去锁定同一条记录是怎么处理的

  • 虽然用的不同辅助索引,但是相应的聚簇索引也会加锁,也就是主键会加锁,这样就止并发修改了

间隙锁(Gap Lock)与临键锁(Next-key Locks)

间隙锁

  • 间隙锁,锁的就是两个值之间的空隙。
  • 间隙锁是在可重复读隔离级别下才会生效
  • 在普通索引列上,不管是何种查询,只要加锁,都会产生间隙锁,这跟唯一索引不一样;
  • 在普通索引和唯一索引中,数据间隙的分析,数据行是优先根据普通索引排序,再根据唯一索引排序。

产生的条件

  • 使用普通索引锁定;
  • 使用多列唯一索引;
  • 使用唯一索引锁定多行记录。

间隙锁开启状态处理:innodb_locks_unsafe_for_binLOG

  • 默认值为OFF,即启用间隙锁。
  • 此参数是只读模式,如果想要禁用间隙锁,需要修改 my.cnf(windows是my.ini) 重新启动才行。
  • 查看是否禁用:show VARiables like 'innodb_locks_unsafe_for_binlog';

间隙锁的范围说明

|id|name| |-|-|-| |1|a| |5|d| |10|f| |100|z|

  • 唯一索引:id的间隙 SELECT * From table WHERE id > 3 AND id < 7 FOR UPDATE; 产生的间隙为(1,10】
  • 普通索引:name的间隙 SELECT * From table WHERE name = '5' FOR UPDATE; 产生的间隙为(1,10】

临键锁(Next-key Locks)

  • 行锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间
  • 这是Innodb在可重复读提交下为了解决幻读问题时引入的锁机制,
  • MySQL 默认隔离级别是RR(可重复读),在这种级别下,如果你使用 select in share mode 或者 select for update 语句,那么InnoDB会使用临键锁(记录锁 + 间隙锁),因而可以防止幻读;
  • 即使你的隔离级别是 RR(可重复读),如果你这是使用普通的select语句,那么此时 InnoDB 引擎将是使用快照读,而不会使用任何锁,因而还是无法防止幻读。

脚本宝典总结

以上是脚本宝典为你收集整理的mysql的锁全部内容,希望文章能够帮你解决mysql的锁所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。