暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

141.MySQL 有哪些锁?

每天一个开发小知识。


开局一张图



今天,我们梳理下 MySQL 中涉及到的锁。


由于 MyISAM 存储引擎没有表级锁,所以,上图可以认为是 InnoDB 对应的锁。


乐观锁


每次取数据时,都乐观的认为不会有其它事务在接下来的时间修改该数据,所以读取数据时不会加锁。


每次更新数据时,会先判断数据是否已被其它事务修改,如果是,则放弃更新;否则,进行更新操作。


用于判断数据是否已被其它事务更新,常用的机制有数据版本记录机制


悲观锁


每次读取数据时,都悲观的认为会有其它事务在接下来的时间修改该数据,所以读取数据时会加锁,避免其他事务修改该数据。


行级锁


开销大,加锁慢,可能出现死锁,并发高。


页级锁


开销一般,加锁速度一般,可能出现死锁,并发一般。


表级锁


开销小,加锁快,不会出现死锁,并发低。


行(表)共享锁(S)


类似多线程中的读锁,共享锁可以和其它共享锁同时访问数据,但是共享锁不可以和排他锁同时访问数据。


行(表)排他锁(X)


类似多线程中的写锁,排他锁使得当前事务独占数据,因此,不可和共享锁和其它排他锁同时访问数据。


意向表共享锁(IS)


一个事务在给一行数据加行共享锁时,必须先获得表的意向表共享锁。


意向表排他锁(IX)


一个事务在给一行数据加行排他锁时,必须先获得表的意向表排他锁。


行共享锁,行排他锁,意向表共享锁和意向表排他锁的兼容关系如下:



便于记忆:


  1. 排他锁与任何锁都不兼容;

  2. 意向锁与任何意向锁兼容;

  3. 共享锁与排他锁,意向排他锁都不兼容。


间隙锁


我们知道,在 MySQL 事务隔离级别的可串行化级别下,没有幻读问题。


这是因为可串行化级别下,MySQL 给每个 select 语句加上了间隙锁。


例如,对于下面查询语句:


    select * from t_book where 0<id and id<100;


    不管 id 在不在表中,只要 id 在 (0, 100) 范围内,则都加上了锁。


    表中已经存在的 id,加上的锁叫行共享锁;


    表中不存在的 id,加上的锁叫间隙锁。


    每天一个开发小知识,今天你学废了吗?

    文章转载自每天一个开发小知识,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论