MySQL有两个核心的知识点,索引和锁。前几篇文章已经详细讲解了MySQL索引实现机制,今天再一起学习一下MySQL的锁。

1 为什么要加锁?

当多个事务并发操作同一批数据的时候,如果不加锁,就无法保证事务的隔离性,最后导致数据错乱。

加锁是为了保证并发操作下数据的正确性。

2 锁的分类有哪些?

按锁的粒度可分为:表锁、页面锁、行锁、记录锁、间隙锁、临键锁

按锁的属性可分为:共享锁、排它锁

按加锁机制可分为:乐观锁、悲观锁

下面依次介绍一下这几种锁:

表锁:

MyISAM和InnoDB引擎均支持表锁。

优点:开销小,加锁快,不会出现死锁。

缺点:锁定力度大,发生锁冲突概率高,并发度最低。

加锁方式:

# 对user表加读锁
lock table user read;
# 同时对user表加读锁,对order表加写锁
lock tables user read, order write;

什么情况下需要用到表锁?

  1. 当需要更新表中的大部分数据
  2. 事务涉及到多张表,业务逻辑复杂,加表锁可以避免死锁。

页面锁:

优点:开销和加锁速度介于表锁和行锁之间。

缺点:会出现死锁,锁定粒度介于表锁和行锁之间,并发度一般。

目前只有BDB引擎支持页面锁,应用场景较少。

行锁:

只有InnoDB引擎支持行锁,另外锁是加在索引上面的。

优点: 开销大,加锁慢;会出现死锁。

缺点:锁定粒度小,发生锁冲突的概率低,并发度高。

另外记录锁、间隙锁、临键锁均属于行锁。

记录锁(Record Locks):

即对某条记录加锁。

# 对id=1的用户加锁
update user set age=age+1 where id=1;

间隙锁(Gap Locks):

即对某个范围加锁,但是不包含范围的临界数据。

# 对id大于1并且小于10的用户加锁
update user set age=age+1 where id>1 and id<10;

上面SQL的加锁范围是(1,10)。

临键锁(Next-Key Locks):

由记录锁和间隙锁组成,既包含记录本身又包含范围,左开右闭区间。

# 对id大于1并且小于等于10的用户加锁
update user set age=age+1 where id>1 and id<=10;

共享锁(又称读锁、S锁):

作用:防止其他事务修改当前数据。

加锁方式:

在select语句末尾加上lock in share mode关键字。

# 对id=1的用户加读锁
select * from user where id=1 lock in share mode;

排他锁(又称写锁、X锁):

作用:防止其他事务读取或者更新当前数据。

加锁方式:

在select语句末尾加上for update关键字。

# 对id=1的用户加写锁
select * from user where id=1 for update;

乐观锁:

总是假设别人不会修改当前数据,所以每次读取数据的时候都不会加锁,只是在更新数据的时候通过version判断别人是否修改过数据,Java的atomic包下的类就是使用乐观锁(CAS)实现的。

适用于读多写少的场景。

加锁方式:

  1. 读取version

    select id,name,age,version from user id=1;
  2. 更新数据,判断version是否修改过。

    update user set age=age+1 where id=1 and version=1;

悲观锁:

总是假设别人会修改当前数据,所以每次读取的时候,总是加锁。

适用于写多读少的场景。

加锁方式:

# 加读锁
select * from user where id=1 lock in share mode;
# 加写锁
select * from user where id=1 for update;

本文知识点总结:

文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。

MySQL十种锁,一篇文章带你全解析的更多相关文章

  1. MYSQL(基本篇)——一篇文章带你走进MYSQL的奇妙世界

    MYSQL(基本篇)--一篇文章带你走进MYSQL的奇妙世界 MYSQL算是我们程序员必不可少的一份求职工具了 无论在什么岗位,我们都可以看到应聘要求上所书写的"精通MYSQL等数据库及优化 ...

  2. MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL

    MYSQL(进阶篇)--一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL 温馨提醒:该文章大 ...

  3. 一篇文章带你了解NoSql数据库——Redis简单入门

    一篇文章带你了解NoSql数据库--Redis简单入门 Redis是一个基于内存的key-value结构数据库 我们会利用其内存存储速度快,读写性能高的特点去完成企业中的一些热门数据的储存信息 在本篇 ...

  4. MySQL命令,一篇文章替你全部搞定

    MySQL命令,一篇文章替你全部搞定 MySQL的基本操作可以包括两个方面:MySQL常用语句如高频率使用的增删改查(CRUD)语句和MySQL高级功能,如存储过程,触发器,事务处理等.而这两个方面又 ...

  5. 一篇文章带你掌握主流数据库框架——MyBatis

    一篇文章带你掌握主流数据库框架--MyBatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射. 在之前的文章中我们学习了MYSQL和JDBC,但是这些东西远远不 ...

  6. 一篇文章带你掌握主流基础框架——Spring

    一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...

  7. 一篇文章带你掌握主流办公框架——SpringBoot

    一篇文章带你掌握主流办公框架--SpringBoot 在之前的文章中我们已经学习了SSM的全部内容以及相关整合 SSM是Spring的产品,主要用来简化开发,但我们现在所介绍的这款框架--Spring ...

  8. 一篇文章带你掌握MyBatis简化框架——MyBatisPlus

    一篇文章带你掌握MyBatis简化框架--MyBatisPlus 我们在前面的文章中已经学习了目前开发所需的主流框架 类似于我们所学习的SpringBoot框架用于简化Spring开发,我们的国人大大 ...

  9. 一篇文章带你了解服务器操作系统——Linux简单入门

    一篇文章带你了解服务器操作系统--Linux简单入门 Linux作为服务器的常用操作系统,身为工作人员自然是要有所了解的 在本篇中我们会简单介绍Linux的特点,安装,相关指令使用以及内部程序的安装等 ...

随机推荐

  1. Java学习day2

    今天学习了Java的数据类型.运算符.选择循环结构以及数组. Java所有的关键字全部小写 Java的数据类型与c语言相似,但是c语言定义数组时可以不主动对其初始化,而Java则必须先初始化,有动态和 ...

  2. SpringBoot 三层架构 Controller、Service、Dao作用和关系详解

    首先创建一个springboot项目. model层 model层也叫pojo层或者entity层,个人比较喜欢pojo层. 一般数据库的一张表对应一个pojo层,并且表中所有字段都在pojo层都一一 ...

  3. Gson解析:java.lang.IllegalArgumentException: declares multiple JSON fields named status 问题的解决

    在一次写定义系统统一返回值的情况下,碰到了java.lang.IllegalArgumentException: declares multiple JSON fields named status这 ...

  4. BUUCTF-Web:[GXYCTF2019]Ping Ping Ping

    题目 解题过程 1.题目页面提示?ip=,猜测是让我们把这个当做变量上传参数,由此猜想是命令注入 2.用管道符加上linux常用命令ls(windwos可以尝试dir)试试 所谓管道符(linux)的 ...

  5. 详解Docker中Image、Container与 Volume 的迁移

    开源Linux 长按二维码加关注~ 上一篇:Linux Used内存到底哪里去了? 已经部署的容器化服务,也不是不需要维护的.而且,由于生产环境往往有这样那样的严格要求,往往需要些非常规操作.Imag ...

  6. JuiceFS v1.0 beta3 发布,支持 etcd、Amazon MemoryDB、Redis Cluster

    JuiceFS v1.0 beta3 在元数据引擎方面继续增强,新增 etcd 支持小于 200 万文件的使用场景,相比 Redis 可以提供更好的可用性和安全性.同时支持了 Amazon Memor ...

  7. Oracle 19c单实例部署

    目录 Oracle 19c单实例部署: 1.配置yum: 2.安装rpm包: 3.设置hostname: 4.配置hostname解析: 5.配置时钟同步服务(ntp): 6.检查及配置内核参数: 7 ...

  8. 创建进程,join方法,进程对象相关属性和方法,僵尸进程和孤儿进程,守护进程,互斥锁

    创建进程 在python中提供了一个multiprocessing模块可以帮助我们使用多进程解决问题.在multiprocessing 模块中有一个类Process. from multiproces ...

  9. 每日一题20180330-Linux

    一.问题 1.1 统计/var/log/下所有文件个数 1.2 查找出/var/log目录下面修改时间是7天以前,大小在50k到2M之间,并以.log结尾的文件把这些文件复制到/data目录中 1.3 ...

  10. K8S 使用Kubeadm搭建高可用Kubernetes(K8S)集群 - 证书有效期100年

    1.概述 Kubenetes集群的控制平面节点(即Master节点)由数据库服务(Etcd)+其他组件服务(Apiserver.Controller-manager.Scheduler...)组成. ...