查看原文
其他

MySQL:表级锁、行级锁、共享锁、排他锁、乐观锁、悲观锁

康熙 终码一生 2022-09-22

「今日推荐」

Redis 性能优化思路 !

深入浅出!分布式事务常见的 几种解决方案

GitHub访问太慢?快来看看如何给他加速吧!

 

一文读懂所有锁,了解他们的优缺点和使用场景。

表级锁与行级锁


 

表级锁:


  • table-level locking,锁住整个表。

  • 开销小,加锁快。

  • 不会死锁(一次性加载所需的所有表)。

  • 锁粒度大,发生锁冲突概率大,并发效率低。

  • 适合查询。


行级锁:


  • row-level loking,锁住一行记录。

  • 开销大,加锁慢。

  • 会死锁。

  • 锁粒度小,发生所冲突概率小,并发效率高。

  • 适合并发写,事务控制。


并不是直接丢记录行加锁,而是对行对应的索引加锁:

  • 如果sql 语句操作了主键索引,Mysql 就会锁定这条主键索引。

  • 如果sql语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。

  • 在InnoDB中,如果SQL语句不涉及索引,则会通过隐藏的聚簇索引来对记录加锁。

  • 对聚簇索引加锁,实际效果跟表锁一样,因为找到某一条记录就得扫描全表,要扫描全表,就得锁定表。


引擎与锁:


  • MyISAM引擎支持表级锁,不支持行级锁。

  • InnoDB引擎支持表级锁和行级锁,默认为行级锁。

 

共享锁与排他锁


 

共享锁:


  • 有称之为S锁、读锁。

  • 当前线程对共享资源加共享锁,其他线程可以读取此资源、可以继续追加共享锁,但是不能修改此资源、不能追加排他锁。

  • 语法:select id from t_table in share mode;

  • 多个共享锁可以共存,共享锁与排他锁不能共存。


排他锁:


  • 又称之为X锁、写锁。

  • 当前线程对共享资源加排他锁,其他线程不允许读取此资源,不允许追加共享锁,不允许修改此资源,不允许追加排他锁。

  • 语法:

       1. update t_table set a =1; // 数据库的增删改操作默认都会加排他锁

       2. select * from t_table for update;// for update也是一种增删改

  • 排他锁是独占的,不会与其他锁共存。

 

乐观锁与悲观锁


 

乐观锁与悲观锁是逻辑上的锁。


乐观锁:


  • 乐观锁:乐观地认为,并发问题很难发生。

  • 乐观锁虽然认为并发问题很难发生,但并不是不会发生,所以也会有措施防止问题真的产生:每次数据修改都自增版本号version。

  • 进行数据读取时,并不加锁,而是同时读取当前的版本号version1;在对数据进行修改时,要判断当前的版本号version2是否等于之前的版本号version1。

  • 版本号不匹配,则代表着并发问题已产生,所以需要回滚此次操作。

  • 实现方式:版本号机制、CAS。


悲观锁:


  • 悲观锁:悲观地认为,并发问题极易发生。

  • 悲观锁认为并发问题极易发生,所以每次操作,无论读写,都会对记录加锁,以防止其他线程对数据进行修改。

  • 实现方式:数据库的行锁、读锁和写锁。


 

END

 


 


终码一生长按扫描二维码
关注我们 获取更多技术资讯
微信号:zma_1314


往期推荐

我去!微信竟然可以查出行轨迹了,预计又一波情侣要分手?

瞬间几千次的重复提交,看看用 SpringBoot+Redis 如何扛住的

JDK16 正式版发布,网友:别更新了,学不动了~

SpringCloud Alibaba之 Seata 分布式事务

京东架构师:日均 5 亿查询量的ElasticSearch架构如何设计?


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存