• mysql锁机制


      mysql常用的存储引擎有MyISAM和InnoDB,MyISAM只有表锁,InnoDB支持表锁和行锁。我们下面的总结基于InnoDB存储引擎

      1、InnoDB实现了以下两种类型的行锁

      共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

      排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

      2、意向锁

      mysql为了提高冲突监测性能而存在的一种锁。是给其上一级所加的锁,意向锁是InnoDB自动加的,不需用户干预。所以在mysql中通常为表锁。

      意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

      意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

      意向锁的作用:比如一个事务,给两行加了排他锁,又有一个事务想要给整个表加共享锁,这个时候就要去查看所有的表的行是否有锁策略不能加共享锁。如果有了意向锁,那么事务1就能再给两行加排他锁的同时,给整个表加IX, 这样事务2不用遍历就能知道不可以加S锁了。

      3、悲观锁与乐观锁:

      悲观锁:使用悲观锁,则会在操作期间全程对数据进行加锁,其他人不能再次修改。这样会造成比较长时间的阻塞。 适用于短事务,写量比较大的情况。

      乐观锁:乐观锁通过在数据库中新增一个version字段,操作后给version + 1. 提交时比较传参的version和数据库中version的大小,如果相等则表示在这期间没有session来更新这条件记录,则提交。

      4、死锁

      和java中死锁机制差不多,两个事务都去拿两张表的锁,拿锁顺序相反并且有间隔,则会造成死锁,解决办法:一次锁所有数据;保持锁的顺序;允许死锁,然后kill掉代价最小的事务,回滚。

      5、间隙锁

      当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁,对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。被锁定的区域,不能插入或者删除数据,以防止幻读。

      特别说明的是,InnoDB除了通过范围条件加锁时使用间隙锁外,如果使用相等条件请求给一个不存在的记录加锁,InnoDB也会使用间隙锁。在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这往往会造成严重的锁等待。因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。

      6、使用行锁的注意事项

      InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。

      由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点;当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

      即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。

      7、什么时候使用表锁

      对于InnoDB存储引擎的表,在绝大部分情况下都应该使用行级锁,因为事务和行锁往往是我们之所以选择InnoDB表的理由。但在个别特殊事务中,也可以考虑使用表级锁。

      第一种情况是:事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间锁等待和锁冲突,这种情况下可以考虑使用表锁来提高该事务的执行速度。

      第二种情况是:事务涉及多个表,比较复杂,很可能引起死锁,造成大量事务回滚。这种情况也可以考虑一次性锁定事务涉及的表,

    从而避免死锁、减少数据库因事务回滚带来的开销。

      8、语句与锁

      nnoDB 的行锁是基于索引的,如果没有索引,或者不能使用索引则是表锁

      select … from 一致性非阻塞读,不上锁。

      select … from where lock in share mode 共享锁

      select … from where … for update 排他锁

      update .. where 排他锁

      delete … from 排他锁

      

  • 相关阅读:
    Python进阶03 模块
    Python进阶02 文本文件的输入输出
    Python进阶01 词典
    Python基础10 反过头来看看
    Python基础09 面向对象的进一步拓展
    Python基础08 面向对象的基本概念
    Python基础07 函数
    Vuex源码分析(转)
    Vue2.x双向数据绑定
    Angular2的双向数据绑定
  • 原文地址:https://www.cnblogs.com/hhhshct/p/9817973.html
Copyright © 2020-2023  润新知