数据库各种锁详解

文章目录

  • 排他锁
  • 共享锁
  • 更新锁
  • 意向锁
  • 锁的粒度
  • 数据库自动加锁
  • 手动加锁
  • 各种锁之间的兼容问题

排他锁

Exclusive Locks,英译:排他锁,简称 X 锁,又称为写锁或独占锁。排他锁分为表级排他锁和行级排他锁。

如果事务 T1 对数据行对象 A 加上了行级排他锁,那么事务 T1 可以对数据行对象 A 进行读取和更新操作,其他事务则只能对数据行对象 A 进行读取操作,而不能进行更新操作,并且其它事务不能再往数据行对象 A 上加任何类型的锁,直到 T1 释放了行级排他锁。

MySQL 的 InnoDB 引擎默认的修改数据语句 update、delete、insert 都会自动给涉及到的数据加上行级排他锁,而 select 语句默认不会加任何锁,如果查询的时候要加行级排他锁可以使用 select ...for update 语句,加行级共享锁可以使用 select ... lock in share mode 语句。

所以加过行级排他锁的数据行其他事务是不能通过 for updatelock in share mode 方式查询数据,但可以直接通过 select ...from... 查询数据,因为普通查询没有加任何锁。

事务 T1 如果对某张表加了表级排他锁,表示事务 T1 可以对该表中的所有记录进行查询和修改,而其它事务只能查询不能修改。并且其它事务不能再往这张表加任何类型的表级锁,也不能给表中的数据行加任何的行级锁。

共享锁

Shared Lock,英译:共享锁,简称 S 锁,又称读锁。共享锁分为表级共享锁和行级共享锁。

顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。即共享锁不阻塞其他事务的读操作,但阻塞写操作。

当事务 T1 为数据行对象 A 加上行级共享锁后,事务 T1 可以对数据行对象 A 进行读操作,但不能进行写操作,并且事务 T2 可以再次对数据行对象 A 加行级共享锁,但是不能加行级排他锁,也不能加表级排他锁。大家都可以正常地读取数据行对象 A,在数据行对象 A 上的所有共享锁释放之前,任何事务不可以对数据行对象 A 进行写操作。

数据行对象 A 可以共存多个行级共享锁,这被称为行级共享锁兼容。加了行级共享锁的数据行对象 A 不能再加行级排他锁,所以行级共享锁和行级排他锁是不兼容的。

当事务 T1 为某张表添加了表级共享锁,表示事务 T1 可以查看表中的所有记录,但是不能修改,而且其它事务也只能查看数据不能修改数据。但是其它事务可以再往这张表添加表级共享锁和意向共享锁,其它事务也可以往这张表中的记录添加行级共享锁;但是其它事务不能再往这张表添加表级的排他锁,也不能添加意向排他锁,其它事务也不能往这张表中的记录添加行级排他锁。

更新锁

Update Lock,英译:更新锁,简称 U 锁。更新锁只有行级的更新锁。

当事务 T1 给数据行对象 A 加上更新锁后,代表数据行对象 A 将在稍后被更新。更新锁允许其他事务在事务 T1 操作更新之前读取数据行对象 A,但不可以修改。其他事务修改数据行对象 A 之前会先往数据行对象 A 加行级排他锁,但是发现数据行对象 A 已存在 U 锁,所以加行级排他锁失败,只能等待 U 锁释放。

更新锁与行级共享锁兼容;更新锁与表级共享锁不兼容;更新锁与更新锁互不兼容;更新锁与行级排他锁不兼容,更新锁与表级排他锁不兼容。

因此数据行对象 A 不可以再添加更新锁,但是可以添加行级共享锁,但是添加行级共享锁的意义不大,因为事务 T1 找到需要更新的数据时,更新锁直接转为行级排他锁,开始更新数据,不需要等待其他事务释放行级共享锁,所以在有更新锁的数据资源上加行级共享锁就毫无意义了。

意向锁

在数据行对象上加 U、X、S 之前都会先为表或者页加意向锁。意向锁是一种表级锁,表明“某个事务对表中的记录加了某种锁或准备加某种锁。

常用的意向锁有三种:
1.Intent Share Lock,英译:意向共享锁,简称 IS 锁

事务 T1 在给数据行对象添加行级 S 锁前,要先获得 IS 锁。如果表被加了 IS 锁,说明某个事务对这个表中的某些数据行加了行级 S 锁。当其它事务想要在这个表上加一个表级排他锁时,发现这个表已经加了意向共享锁,那么就不可以加表级的排他锁了。

2.Intent Exclusive Lock,英译:意向排他锁,简称 IX 锁

事务在请求行级 X 锁前,要先获得 IX 锁
事务 T1 修改 user 表的数据行对象 A,会给数据行对象 A 上一把行级的排他锁,但是在给数据行对象 A 上行级排他锁前会先给 user 表上一把意向排他锁,这时事务 T2 要给 user 表上一个表级的排他锁就会被阻塞。

3.Share Intent Exclusive Lock,英译:共享意向排他锁,简称 SIX 锁

共享意向排他锁的意思是,某事务要读取整个表,并更新其中的某些数据。

我质疑存在这种锁,在网络上找不到关于共享意向排它锁的任何资料。

锁的粒度

锁的粒度指的是锁生效的范围,即行锁、页锁、表锁等。锁的粒度一般由数据库自主管理,不同的事务隔离级别,数据库会有不同的加锁策略(比如加什么类型的锁,加什么粒度的锁)。

数据库自动加锁

其实锁在大多数情况下都是数据库自动加的,数据库会根据隔离级别的不同,按照策略来加锁。

比如这么一条语句:

mysql> update student set class = '高二(3)班'; 

通过性能分析工具 Profiler 跟踪 sql 发现,数据库系统会逐行先获取 U 锁,然后转为 X 锁,对数据行进行更新,更新完后并不释放 X 锁,接着继续获取下一行的 U 锁,转为 X 锁,更新数据…,不断重复以上流程,直到全部数据行更新完成后,再逐行释放掉所有的 X 锁。

而如果加上 where 条件,如:

mysql> update student set class = '高二(3)班' where name = 'liudehua';

如果字段 name 没有索引,则逐行获取 U 锁,如果符合条件,转为 X 锁,执行更新,不释放 X 锁;如果不符合条件,释放 U 锁。

如果有索引的话,则不需要全表扫描逐行处理,而是直接定位到要更新的数据行,然后逐行加上 X 锁,接着执行更新,更新后不释放 X 锁,直到所有定位到的数据行更新完成后,再逐行释放 X 锁。

手动加锁

手动加行级排他锁,如下所示:

mysql> begin; -- 开始事务
Query OK, 0 rows affected (0.00 sec)mysql> select * from account where id = 5 for update; -- 查询到的数据行全部加上行级的排他锁
+----+----------+---------+
| id | NAME     | balance |
+----+----------+---------+
|  5 | zhangsan | 1000.00 |
+----+----------+---------+
1 row in set (0.00 sec)

手动加行级共享锁,如下所示:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from account where id = 5 lock in share mode;
+----+----------+---------+
| id | NAME     | balance |
+----+----------+---------+
|  5 | zhangsan |    0.00 |
+----+----------+---------+
1 row in set (0.01 sec)

手动给表加表级的排他锁,如下所示:

mysql> lock tables account write; -- 给表account加排他锁,即写锁
Query OK, 0 rows affected (0.00 sec)

注:
1.会话 S1 对表 account 加上表级排他锁后,其它会话不能对该表 account 进行查询和修改操作。
2.会话 S1 对表 account 加上任何表级锁后,该会话不能对其它非锁表进行任何的操作。

手动给表加表级的共享锁,如下所示:

mysql> lock tables account read; -- 给表account 加共享锁,即读锁
Query OK, 0 rows affected (0.00 sec)

给多个表加表级锁,如下所示:

mysql> lock table user write,account write;
Query OK, 0 rows affected (0.00 sec)

手动解锁,如下所示:

mysql> unlock tables;

各种锁之间的兼容问题

-行级 S行级 U行级 X表级 S表级 XISIX
行级 S兼容加了 S 锁不能再加 U 锁,但是先加 U 锁,可以再加 S 锁不兼容兼容不兼容兼容兼容
行级 U加了 S 锁不能再加 U 锁,但是先加 U 锁,可以再加 S 锁不兼容不兼容不兼容不兼容兼容兼容
行级 X不兼容不兼容不兼容不兼容不兼容兼容兼容
表级 S兼容不兼容不兼容兼容不兼容兼容不兼容
表级 X不兼容不兼容不兼容不兼容不兼容不兼容不兼容
IS兼容不兼容不兼容兼容不兼容兼容兼容
IX兼容兼容兼容不兼容不兼容兼容兼容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

activiti dmn_新的DMN编辑器预览

activiti dmnWorkbench 7.13.0.Final于10月16日星期二发布,此版本带来了许多有趣的功能和重要的修复程序。 亮点之一是作为技术预览功能的新DMN编辑器,该功能仍在开发中,但您可以开始使用。 在本文中,您将学习如何启用DMN编辑器预…

MySQL的索引存储数据结构BTree和B+Tree的区别

文章目录BTree 原理示意图BTree 原理示意图BTree的树层级很少BTree 可以高效支持范围查找BTree 原理示意图 注:BTree 就是 B-Tree,实际上官方并没有 B-Tree 的说法。 BTree 原理示意图 BTree的树层级很少 BTree 的数据存在每个节点中,所以每…

jdk11 javafx_JDK 11上的JavaFX

jdk11 javafx在JFX第11版发布后,人们对JavaFX与JDK的解耦感到百感交集。 我们许多人认为现在是时候告别JavaFX并改用另一种GUI技术了,而另一些人对此情况感到高兴。 他们认为,将JavaFX与Oracle分离开来,并致力于将其作为开源社区驱…

配置Java环境变量

JAVA环境变量配置 一、新建系统变量 新建变量,找到安装目录新建一个JAVA_HOME,路径为bin目录的前一级目录。 可以安装多个JAVA版本,然后新建不同的JAVA_HOME名称,然后填写bin目录的前一级路径。 二、编辑环境变量 找到path,然后编辑%JAVA…

MySQL的存储引擎InnoDB,B+Tree数据结构索引的实现原理图(聚簇索引/聚集索引)

1.表数据文件本身就是按BTree组织的一个索引结构文件 2.InnoDB的BTree的索引数据结构中,表数据和索引数据合并在一起,即叶子节点包含了完整的数据记录,这样的索引叫聚簇索引。

idea 切换java11_Java 11就在这里,您准备好进行切换了吗?

idea 切换java11在应该将Java 9发行版“震撼我们的世界”一年之后,我们一直在等待的LTS版本终于出现了 我们知道,大多数开发人员,团队,公司等尚未通过Java 8进行更新。 即使去年发布了模块Java 9,随后在3月又发布了Ja…

编译Java源文件

编写 新建hello.java文件 注意类名要和文件名称相同,如果不相同会提示错误 public class hello{public static void main(String[] args) {System.out.println("HelloWorld");} }编译 javac hello.java 编译会生成相应的.class文件。 运行 java hell…

oracle jdk_两个Oracle JDK的故事

oracle jdk最近 ,人们担心 Java开发人员现在会无意中使用错误的Oracle提供的JDK实现(从JDK 11开始 ), Oracle提供了开源OpenJDK的构建 ,并且还主要基于OpenJDK源提供了商业JDK的构建。 下表比较并对比了Oracle提供的两…

安装MAVEN和找不到JAVA_HOME问题原因

一、MAVEN安装 1.将下载好的MAVEN解压 2.配置MAVEN环境变量 MAVEN_HOME3.3.9 配置path 3.配置本地仓库 打开settings.xml进行修改 在MAVEN下新建一个repository文件夹 4.配置阿里MAVEN仓库配置 每次去阿里云下载jar包 <mirror><id>AliMaven</id>&…

数据库中的二级索引_普通索引_辅助索引

普通索引、二级索引、辅助索引是同个东西。 假设有张表的字段为 name&#xff0c;这个字段添加普通索引&#xff08;也叫二级索引&#xff09;&#xff0c;其存储引擎为 InnoDB&#xff0c;那么这个 name 索引的结构图&#xff1a;

2018-12 jdk_JDK 12新闻(2018年9月13日)

2018-12 jdk由于计划于本月晚些时候&#xff08;2018年9月25日&#xff09;发布JDK 11的 一般可用性 &#xff0c;是时候开始更仔细地研究JDK 12了 。 在OpenJDK jdk-dev邮件列表上的标题为“ JDK 12的计划时间表 ”的消息中 &#xff0c; 马克赖因霍尔德 &#xff08; Mark R…

idea连接mysql数据库时连接显示错误caching_sha2_password

问题描述 Connection to paradigmlocalhost failed. Unable to load authentication plugin caching_sha2_password.问题原因 mysql8之前的版本使用的密码加密规则是mysql_native_password&#xff0c;但是在mysql8则是caching_sha2_password&#xff0c;所以需要修改密码加密…

MySQL联合索引原理_复合索引_组合索引_多列索引

文章目录联合索引原理示意图联合索引就是复合索引、组合索引、多列索引。联合索引原理示意图

fluent design_Fluent Design单选按钮,复选框,选择框,Java菜单

fluent design这次我对JMetro进行了重大更新。 3.8版带来了以下新的Fluent Design &#xff08;FDS&#xff09;启发风格&#xff08;深色和浅色&#xff09;和更新&#xff1a; 新的单选按钮样式&#xff1b; 复选框的新样式&#xff1b; 菜单的新样式&#xff1b; 更新了…

MySQL的explain工具介绍

文章目录介绍explain extendedshow waringsexplain partitionsid 字段select_typetypekeypossible_keyskey_lenkey_len 计算规则refrowsextra介绍 使用 explain 可以模拟优化器执行 SQL 语句&#xff0c;会返回 SQL 语句的执行计划信息&#xff0c;但是不会真正去执行这条 SQL…

jetty设置双向ssl_在Jetty中设置SSL

jetty设置双向ssl当您必须快速启用SSL并陷入困境时&#xff0c;您是否遇到了问题&#xff1a;-( 你并不孤单&#xff0c;我将分享我的痛苦和一些学习。 我将分享在码头上启用SSL的步骤。 警告&#xff1a;仅将以下说明用于开发人员设置和生产&#xff0c;请联系您的安全专家…

使用Thumbnailator压缩照片

导入依赖 <dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version></dependency>代码 package com.asx.hyd.non.trs;import net.coobird.thumbnailator.Thumbnails;impo…

MySQL的索引优化

文章目录全值匹配最左前缀原则不在索引列上使用函数&#xff0c;会导致索引失效而转向使用全表扫描范围条件右边的索引列会失效尽量使用覆盖索引使用不等于操作符无法使用索引is null&#xff0c;is not null 一般情况下也无法使用索引like 以通配符开头的&#xff0c;索引会失…

cuba 平台_认识CLI for CUBA平台

cuba 平台毫无疑问&#xff0c;软件开发人员&#xff08;尤其是Java开发人员&#xff09;的世界充满了键盘狂热者&#xff0c;最好通过单击一下鼠标键入10-15个字母。 而且我们的社区也不例外&#xff0c;因此我们经常被问到“如何在没有CUBA Studio的情况下启动项目&#xff1…

关闭zookeeper进程

查看端口是否占用 netstat -ano|findstr “2181” 关闭相应进程 tskill 端口号 MAC启动配置文件 找到对应路径 /Users/mac/Desktop/soft/software/apache-zookeeper-3.8.0/bin启动zookeeper ./zkServer.sh start查看状态 ./zkServer.sh status关闭zookeeper ./zkServe…