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. vue学习day02

    vue 指令 1. 内容渲染指令 v-text 指令的缺点:会覆盖元素内部原有的内容! {{ }} 插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容! v-html 指令的作用: ...

  2. Glade To Code 介绍

    Glade To Code 简介 根据 Glade 文件生成指定语言的 GTK 代码的工具 使用说明 python3 glade-to-code.py -l [语言类型] -i [输入 Glade 文 ...

  3. ASP.NETCore统一处理404错误都有哪些方式?

    当未找到网页并且应用程序返回 404 错误时,ASP.NET Core MVC 仅呈现通用浏览器错误页面,如下图所示 这不是很优雅,是吗? 我们平时看到的404页面一般是这样的 还有这样的 试了下京东 ...

  4. Percona停服俄罗斯

    2022年3月9日,MySQL重要分支Percona宣布,他们将停止与俄罗斯和白俄罗斯的组织开展新业务,直至另行通知. Percona为支持员工而采取的一些行动如下: 已经在乌克兰目前安全的部分获得了 ...

  5. .NET Core 中的 Logging 简单实用 - 记录日志消息显示到控制台

    .NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API. 本文介绍了如何将日志记录 API 与内置提供程序一起使用. 本文中所述的大多数代码示例都来自 .Net 5 应用. ...

  6. os模块,sys模块,json模块,subprocess模块

    os模块 一·什么是os模块 os模块提供了多数操作系统的功能接口函数.当os模块被导入后,它会自适应于不同的操作系统平台,根据不同 的平台进行相应的操作,在python编程时,经常和文件.目录打交道 ...

  7. Linux磁盘和文件系统知识总结

    硬盘操作 为什么要给硬盘分区? 如果你需要在一块硬盘上用到多个文件系统,那么你就需要对硬盘进行分区,以便用不同的分区支持不同的文件系统.(但一个硬盘只能有一个分区表!)反过来说,如果你整块硬盘都用同样 ...

  8. 三、单redis升级redis集群+哨兵

    针对假如已经是安装了redis,只是是单部署,需要把他切换成redis集群+哨兵模式,我因为偷懒,就写了个脚本来执行,各位看官,请品~你品~你细品~ 首先准备个升级包,放到任意路径,内容如下: 第一个 ...

  9. 如何生成一个java文档

    如何生成一个java文档 众所周知,一个程序给别人看可能可以看懂,几万行程序就不一定了.在更多的时候,我们并不需要让别人知道我们的程序是怎么写的,只需要告诉他们怎么用的.那么,api文档就发挥了它的作 ...

  10. Mock 之搭建本地 MockJs

    Mock 之搭建本地 MockJs 一.目的 模拟后端接口 二.发请求 1. install npm install axios 2. 配置 src/utils/request.js import a ...