mysql中的锁浅析

news2024/12/23 1:16:48

在这里插入图片描述

前言

MySQL 锁机制是保证多个并发事务同时访问数据库时数据一致性的重要手段,也是 MySQL 的重要特性之一。在实际开发使用 MySQL 数据库时,了解并掌握 MySQL 的锁机制非常重要,因为不正确的锁机制使用很容易出现严重的性能瓶颈和数据不一致等问题。

一、MySQL 的锁分类

MySQL 中的锁可以分为共享锁和排它锁。共享锁和排它锁是两种不同的锁类型,在不同的场景下发挥着不同的作用。相比较而言,共享锁更适合在读多写少的场景下使用,而排它锁更适合在写多读少的场景下使用。

1. 共享锁(Shared Locks,简称 S 锁)

共享锁指的是多个事务可以同时获得对一个相同资源的锁定,这些事务可以读取但不能修改资源。多个共享锁可以共存,各自都可以读取资源,但是不能够对其进行修改,直到所有的共享锁都被释放为止。

2. 排它锁(Exclusive Locks,简称 X 锁)

排它锁是指一个事务获得资源的锁定后,其他事务就不能再对该资源进行任何锁定,包括共享锁和排它锁。此时,有排它锁的事务既可以读取也可以修改资源,其他任何事务都没有权限读取和修改这个资源,直到当前事务释放了这个锁。
在这里插入图片描述

二、MySQL 的锁粒度分类

MySQL 中的锁还可以按照锁定的粒度大小进行分类。根据粒度大小不同,MySQL 的锁可以分为表锁、行锁、页锁等不同的类型。

1. 表锁

表锁是 MySQL 中最大的锁粒度,指对一整张表进行加锁。当一个事务获得一个表锁后,其他事务就不能对该表进行任何修改操作,直到该事务释放了对该表的锁定。表锁往往被用于一些特定的场景,比如备份、统计、DDL 操作等。MySQL 中的 MyISAM 存储引擎就是使用表锁的例子,它在执行 DML 操作时都会对整张表进行锁定操作。

-- 在 MyISAM 存储引擎中使用表级锁,锁定一个表
LOCK TABLES table_name WRITE;

-- 执行修改操作
UPDATE table_name SET column_name = value WHERE condition;

-- 释放表级锁
UNLOCK TABLES;

2. 行锁

行锁是 MySQL 中最小的锁粒度,指对一行记录进行加锁。当一个事务获得一个行锁后,其他事务就不能对该行进行任何修改操作,直到该事务释放了对该行的锁定。行锁可以精确地控制锁定的粒度,避免不必要的锁定操作。MySQL 中的 InnoDB 存储引擎就是使用行锁的例子,它在执行修改操作时都会对涉及到的行进行锁定操作。

-- 在 InnoDB 存储引擎中使用行级锁,锁定一行数据
SELECT * FROM table_name WHERE primary_key = 1 FOR UPDATE;

-- 执行修改操作
UPDATE table_name SET column_name = value WHERE primary_key = 1;

-- 释放行级锁
COMMIT;

3. 页锁

页锁是介于表锁和行锁之间的一种锁粒度,指对一个数据页进行加锁。当一个事务获得一个页锁后,其他事务就不能对该页内的行进行任何修改操作,直到该事务释放了对该页的锁定。MySQL 中的 BDB 存储引擎就是使用页锁的例子,它在执行 DML 操作时会对一页(通常为 4KB)数据进行锁定。
在这里插入图片描述

三、MySQL 的锁机制

MySQL 提供了两种不同的锁机制,分别为悲观锁和乐观锁。下面我们将对这两种锁机制进行详细解释。

1. 悲观锁

MySQL 的悲观锁机制比较常见,也是我们在日常开发中经常使用的锁机制。悲观锁机制认为当多个事务访问同一个数据时,一定会发生冲突从而导致数据不一致情况的发生,因此每次访问该数据时都会进行加锁操作,确保该数据的一致性。

悲观锁的实现方式常见有两种,分别为共享锁和排它锁。在 MySQL 中,悲观锁机制通常是通过使用各种锁类型来实现的。

  • 共享锁(Shared Locks,简称 S 锁):共享锁指的是多个事务可以同时获得对一个相同资源的锁定,这些事务可以读取但不能修改资源。多个共享锁可以共存,各自都可以读取资源,但是不能够对其进行修改,直到所有的共享锁都被释放为止。

  • 排它锁(Exclusive Locks,简称 X 锁):排它锁是指一个事务获得资源的锁定后,其他事务就不能再对该资源进行任何锁定,包括共享锁和排它锁。此时,有排它锁的事务既可以读取也可以修改资源,其他任何事务都没有权限读取和修改这个资源,直到当前事务释放了这个锁。

-- 创建一个 test 表
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- 插入数据
INSERT INTO `test` (`name`) VALUES ('test');

-- session1
START TRANSACTION ;
-- 获取悲观锁
SELECT `name` FROM `test` WHERE `id`=1 FOR UPDATE;
-- 执行一些操作
...
-- 释放悲观锁
COMMIT ;

-- session2
START TRANSACTION ;
-- 获取悲观锁
SELECT `name` FROM `test` WHERE `id`=1 FOR UPDATE;
-- 执行一些操作
...
-- 释放悲观锁
COMMIT ;

上面的示例中,两个 session 都尝试获取 test 表 id 为1的记录的悲观锁,在一个 session 中获取悲观锁后,另一个
session 就必须等待当前 session 结束后才能获取锁,从而实现了数据的排他性。

2. 乐观锁

相对于悲观锁机制而言,乐观锁机制则认为对于同一个数据的并发访问情况是非常少的,因此不会出现数据冲突的情况,从而可以不加锁直接操作该数据。如果没有发现数据冲突,就会成功地进行操作,并且将操作结果更新到数据中;如果发现数据冲突,则会给出相应的提示,并让用户选择相应的处理方式。乐观锁的实现方式通常包括版本号、时间戳、CAS(Compare And Swap)等技术。

-- 创建一个 test 表
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '',
  `version` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- 插入数据
INSERT INTO `test` (`name`, `version`) VALUES ('test', 0);

-- 模拟并发更新
-- session1
START TRANSACTION ;
SELECT @version:=`version` FROM `test` WHERE `id`=1;
-- 当前版本号为0
-- 延时等待 session2 修改提交
-- session2
START TRANSACTION ;
SELECT @version:=`version` FROM `test` WHERE `id`=1;
-- 当前版本号为0,`name` 改为 'test1',`version` 加 1
UPDATE `test` SET `name`='test1',`version`=`version`+1 WHERE `id`=1;
COMMIT ;
-- `test` 表的数据变为(id=1,name='test1',version=1)
-- session1
-- 修改数据
UPDATE `test` SET `name`='test2',`version`=`version`+1 WHERE `id`=1 AND `version`=@version;
-- 若修改成功,则 `test` 表的数据变为(id=1,name='test2',version=1);否则修改失败
COMMIT ;

在这里插入图片描述

四、MySQL 的锁应用场景

MySQL 中的锁可以应用在很多不同的场景中,下面我们将简要介绍其中的两个常用场景。

1. 精细化控制并发访问

在高并发系统中,如果同时有多个事务对某些共享资源进行访问,那么这些事务就会产生资源竞争,容易导致数据出现不一致的情况。因此,在这种情况下,使用 MySQL 的锁机制可以有效地避免资源竞争的出现,保证数据一致性。对于并发访问问题,可以通过使用行级锁定来实现精细化的控制,进而提高数据库的并发处理能力。

2. 防止数据异常处理

在实际开发中,有时候会遇到一些意外情况,导致程序没有正常执行完成就退出,或者其中某些语句卡住,从而影响了后续程序的执行,降低了应用程序的可靠性。这种情况下,如果直接放回一个错误信息或者是空结果,很容易导致数据的异常。因此,使用 MySQL 的锁机制可以避免出现这种情况,保证数据的一致性。在这种情况下,使用排它锁可大大提高 MySQL 数据库的执行效率,同时可以避免出现数据异常情况。
在这里插入图片描述

五、锁小结

MySQL 的锁机制是保证多个并发事务同时访问数据库时数据一致性的重要手段,也是 MySQL 的重要特性之一。在实际开发使用 MySQL 数据库时,了解并掌握 MySQL 的锁机制非常重要,因为不正确的锁机制使用很容易出现严重的性能瓶颈和数据不一致等问题。

MySQL 的锁机制主要包括悲观锁和乐观锁两种。悲观锁机制认为当多个事务访问同一个数据时,一定会发生冲突从而导致数据不一致情况的发生,因此每次访问该数据时都会进行加锁操作,确保该数据的一致性。相比较而言,共享锁更适合在读多写少的场景下使用,而排它锁更适合在写多读少的场景下使用。

总结

综上所述,MySQL 的锁机制可以帮助我们解决多个进程并发访问的问题,保证了数据的安全性和一致性,提高了系统的可靠性。在实际开发中,我们需要根据应用场景具体选择不同类型的锁,避免不必要的资源浪费,提高系统的性能和吞吐量。

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

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

相关文章

尚硅谷大数据hadoop教程_mapReduce

p67 课程介绍 p68概述 p69 mapreduce核心思想 p70 wordcount源码 序列化类型 mapReduce三类进程 p71 编程规范 用户编写的程序分成三个部分:Mapper、Reducer和Driver。 P72 wordcount需求案例分析 p 73 -78 案例环境准备 (1)创建maven…

写代码?文心一言or文言文,谁更胜一筹?新工具或许可堪重任

中国版的ChatGPT“文心一言”写代码能力尚浅 被称为中国版的“ChatGPT”的“文心一言”可以说是上市几个月了,很多用户都受到了邀请码来体验,遗憾的是,小编早就申请了,但还在排队等待中。虽然没有亲自体验过百度的“文心一言”&a…

NET HELPMSG 3534 报错(以及其他一些在配置过程中遇到的问题)

使用了带管理员权限的 PowerShell(即在管理员权限下运行CMD) 然后进行安装和服务启动操作 1、清空 MySQL 下的 data 文件夹; 2、确保系统环境变量中已经配置了 mysql 的 bin 目录到Path中; 3、执行以下命令: sc delet…

基于条件风险价值CVaR的微网动态定价与调度策略(matlab代码)

目录 1 主要内容 模型示意图 电能交易流程 模型亮点 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序复现文章《A cooperative Stackelberg game based energy management considering price discrimination and risk assessment》,建立基于主从博弈的考…

【封装frame模型 Objective-C语言】

一、计算每行的高度 1.计算每行的高度,它就等于最后这个控件, 如果说,当前这行是有配图的,那么这个行高,就等于这个配图最大的Y值,加上一个margin, 如果说,这行是没有配图的 如果说,这行是没有配图的 那么就等于它正文的最大的Y值,加一个margin, 是不是很简单,…

海昌海洋公园携手盖雅工场,数字化人才管理助力企业踏浪前行

五一假期刚刚结束,但各地主题公园里的游客依然爆满。在这种客流高峰期,游客更加关注乐园的细节和服务水平,保障服务品质和顾客体验是各地主题乐园在竞争中脱颖而出的关键因素之一。为此,乐园高峰期需要大量招聘短期工、临时工、兼…

全网最详细,全链路压力测试整理,银行系统项目...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 软件测试银行业务…

k8s污点与容忍

1.前言 污点是给node节点打上污点标签,使得pod不能往该node节点上调度,污点有三种模式,分别是NoSchedule、PreferNoSchedule、NoExecute,容忍是给pod打上和node节点一样的污点标签,使pod能调度到带有该污点标签的node…

为什么使用 Javascript 流程图进行过程可视化

DhtmlxDiagram 是一个随时可用的库,只需几行代码就能生成任何你需要的图表。借助自动布局和实时图编辑器,以整齐的层次结构可视化复杂数据。JavaScript dhtmlxDiagram可以向Web应用程序中添加漂亮的交互式图表,图表和图形。借助这种轻巧而快速…

第六篇、基于Arduino uno,控制180度舵机(SG90)转动——结果导向

0、结果 说明:让舵机转动,需要用PWM来控制,下面的程序是舵机从0度一直转到180度,然后又从180度转到0度的这样一个过程。 1、外观 说明:虽然舵机的型号有很多种,但是只要是180度的舵机,控制方…

XVS-460-15MPI-1-10伊顿触摸屏

​ XVS-460-15MPI-1-10伊顿触摸屏 触摸屏感应到我们手指的触摸是因为当手指触摸屏幕上的一个具体位置时,相当于为屏幕发送了一个精确的电子信号。触摸屏有很多类型,大致分为电阻式触摸屏和电容式触摸屏。目前应用最广泛的是“电容式触摸屏”。 我们手机…

华为OD机试之考勤信息(Java源码)

考勤信息 题目描述 公司用一个字符串来表示员工的出勤信息 absent:缺勤late:迟到leaveearly:早退present:正常上班 现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下: 缺…

Python编程环境搭建:Windows中如何安装Python

在 Windows 上安装 Python 和安装普通软件一样简单,下载安装包以后猛击“下一步”即可。 Python 安装包下载地址:https://www.python.org/downloads/ 打开该链接,可以看到有两个版本的 Python,分别是 Python 3.x 和 Python 2.x&…

Nginx网站服务详解(编译安装及系统服务添加)

目录 一、Nginx的相关知识 1)Nginx的简介 Nginx: Apache: 2)Apache与Nginx的区别 Nginx对比Apache的优势: apache相对于nginx的优点 : 3)Nginx的进程 Nginx有两个进程:…

Java的volatile

介绍 volatile volatile 关键字可以说是 Java 虚拟机提供的最轻量级的同步机制,但是它并不容易被正确、完整地理解,以至于许多程序员都习惯去避免使用它,遇到需要处理多线程数据竞争问题的时候一律使用 synchronized 来进行同步。了解 volat…

Flutter:功能型组件(2)- 弹出菜单、弹出提示

弹出菜单 PopupMenuButton 使用PopupMenuButton&#xff0c;点击时弹出菜单 Center(child: PopupMenuButton<String>(initialValue: Math, // 初始值itemBuilder: (context) {// 子项构造函数return <PopupMenuEntry<String>>[const PopupMenuItem(value:…

svg教程-初始svg

第一章 认识svg 简单来说&#xff1a; 位图&#xff1a;放大会失真图像边缘有锯齿&#xff1b;是由像素点组成&#xff1b;前端的 Canvas 就是位图效果。矢量图&#xff1a;放大不会失真&#xff1b;使用 XML 描述图形。 我在 知乎 上找了一个图对说明一下。 左边是位图&am…

华为开发者大会2023官宣,华为云在憋什么大招?

文丨智能相对论 作者丨沈浪 华为云也坐不住了。 在此之前&#xff0c;百度、阿里、商汤、科大讯飞等国内科技厂商以及微软、谷歌等国际巨头都已经发布了自家的大模型新品以及AIGC等相关应用。而华为云手握盘古大模型&#xff0c;却始终按兵不动&#xff0c;迟迟没有正式进场…

实验篇(7.2) 02. 部署物理实验环境(上)❀ 远程访问

【简介】当大家了解到并不需要很高的代价就可以动手做FortiOS 7.2的实验&#xff0c;很多人愿意尝试使用FortiGate防火墙硬件来学习最验难掌握的远程访问部分&#xff0c;这里我们将学习现场部署一套物理实验环境&#xff0c;让大家看到&#xff0c;在一张桌子上&#xff0c;在…

chatgpt赋能python:Python中大小写转换的方法

Python中大小写转换的方法 在Python编程中&#xff0c;经常需要对文本进行大小写转换的操作。本文将介绍Python中字符串大小写转换的方法&#xff0c;以及如何使用它们来优化你的代码。 方法一&#xff1a;使用upper()和lower()方法 Python中&#xff0c;可以使用字符串对象…