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. 深入理解Kafka核心设计及原理(五):消息存储

    转载请注明出处:https://www.cnblogs.com/zjdxr-up/p/16127749.html 目录: 5.1文件目录布局 5.2消息压缩 5.3日志索引 5.4日志文件及索引文件分 ...

  2. 1s 创建100G文件,最快的方法是?

    在我们日常工作中,为了验证开发的功能,比如:文件上传功能或者算法的处理效率等,经常需要一些大文件进行测试,有时在四处找了一顿之后,发现竟然没有一个合适的,虽然 Linux 中也有一些命令比如:vim. ...

  3. javascript中的宏任务和微任务(一)

    一.宏任务和微任务有哪些 宏任务:setTimeout,setInterval,ajax,dom,宏任务是由浏览器提供的 微任务:promise,async/await,微任务是由es6提供的 二.微 ...

  4. VOC数据集可视化

    from gettext import find import os from xml.etree import ElementTree as ET import cv2 def drawBoxOnV ...

  5. 【dvwa攻略】安全等级low——爆破

    首先登录dvwa,进入到爆破功能模块,在这里是有可以输入账号密码的框的 打开burpsuite,抓包以后发现是get方法 通过在这里输入账号.密码 username password 然后再通过get ...

  6. FreeRTOS --(6)内存管理 heap5

    转载自https://blog.csdn.net/zhoutaopower/article/details/106748308 FreeRTOS 中的 heap 5 内存管理,相对于 heap 4&l ...

  7. 3D打印CLI文件格式的读取

    CLI 英文全称:COMMON LAYER INTERFACE 中文名称:通用层接口. 推荐从官方网址看一下其完整的内容: (https://www.hmilch.net/downloads/cli_ ...

  8. Java学习笔记-基础语法Ⅱ

    成员变量:类中方法外的变量 局部变量:方法中的变量 注意,成员变量有默认初始值,而局部变量需要赋初始值 Java中虽然没有明确规定类必须首字母大写,但为了规范最好大写(因为自己刚刚写的时候就没看清写错 ...

  9. 关于扑克牌的一些讨论——《Fluent Python 2》读书笔记

    一.说明 参考资料为维基百科的 Playing Card 词条,非严肃性论证,只是对代码为什么这么写做讨论. 二.扑克牌的起源 import collections Card = collection ...

  10. spring boot 中接口参数为枚举时的反序列化配置(总结)

    步骤 如果是 GET 请求中需要反序列化枚举值(即 url 中的参数[querystring]),确保以下两点 1.1. 重写 StringToEnumConverterFactory 1.2. 配置 ...