当前位置: 首页 > news >正文

mysql笔记:15. 事务和锁

文章目录

  • 一、事务概述
  • 二、事务基本操作
  • 三、事务保存点
  • 四、事务的隔离级别
    • 1. READ UNCOMMITTED
      • 设置事务的隔离级别
    • 2. READ COMMITTED
    • 3. REPEATABLE READ
    • 4. SERIALIZABLE
  • 五、MySQL的锁
    • InnoDB的锁类型
      • 1. InnoDB的行级锁
      • 2. InnoDB的表级锁
    • 死锁

在开发过程中,我们经常为了完成某一功能而编写一组SQL语句。为了确保每一组SQL语句操作数据的完整性,MySQL引入了事务的管理。事务处理机制可以保证在同一个事务中的操作具有同步性,从而让整个应用程序更加安全。

一、事务概述

在MySQL中,事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成。在程序执行过程中,只要有一条SQL语句执行失败或发生错误,其他语句都不会执行;也就是说,事务中的语句要么都执行,要么都不执行。
数据库之所以提供事务的机制,主要有以下两个目的:

  • 为数据库的一组操作提供了一个从失败中恢复到正常状态的途径,同时保证了数据库即使在异常状态下也仍能保持数据的一致性。
  • 当多个应用程序并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

MySQL中的事务必须满足四个特性,即事务的ACID特性,分别是原子性、一致性、隔离性和持久性。

  1. 原子性(Atomictity)
    原子性是指一个事务必须被视为一个不可分割的最小工作单元,只有事务中所有的数据库操作都执行成功,才算整个事务执行成功。事务中的所有DML操作,要么全部执行成功,要么全部执行失败,不会存在部分执行成功,部分执行失败的情况。事务中如果有任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库的状态退回到执行事务前的状态,相当于事务没有执行过。
  2. 一致性(Consistency)
    一致性是指事务在开始执行前和事务执行结束后,数据库中数据的完整性没有被破坏。数据从一个一致状态转变为另一个一致状态,并且完全符合所有的预设规则,数据不会存在一个中间的状态。
  3. 隔离性(Isolation)
    隔离性是指一个事务在执行时,不会受到其他事务的影响。隔离性保证了未完成事务的所有操作与数据库系统的隔离,直到事务完成之后,才能看到事务的执行结果。当多个用户并发访问数据库时,数据库为每一个用户开启的事务不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
  4. 持久性(Durability)
    持久性是指事务一旦提交,对数据库中数据的修改就是永久性的。数据不会因为系统出现故障而丢失。为了实现事务的持久性,MySQL在提交事务时采用的是预写日志的方式。即提交事务时,先写日志,再写数据。只要日志成功写入,就是事务提交成功。

事务的持久性不能做到百分之百的持久,只能从事务本身的角度来保证永久性,如果一些外部原因导致数据库发生故障(如硬盘损坏),那么所有提交的数据可能都会丢失。

二、事务基本操作

在MySQL中,用户执行的每一条SQL语句默认都会当成单独的事务自动提交。如果想要将一组SQL语句作为一个事务,需要在执行这组SQL语句之前显式地开启事务。事务开启后,后续的每一条SQL语句将不再自动提交。想要提交时,需要手动提交事务。只有事务提交后,事务中的SQL语句才会生效。如果不想提交当前事务,还可以回滚事务。
相关语句如下:

# 开启事务
START TRANSACTION;
# 也可以使用BEGIN
BEGIN;# 提交事务
COMMIT;# 回滚事务
ROLLBACK;

ROLLBACK语句只针对未提交的事务执行回滚,已经提交的事务是不能回滚的。
当执行COMMIT或ROLLBACK后,当前事务就会自动结束。
MySQL中事务不允许嵌套,如果执行START TRANSACTION语句之前,上一个事务还没有提交,则此时会隐式执行上一个事务的提交操作。
MySQL中的事务默认是自动提交,如果用户想要设置事务的自动提交方式,可以通过更改AUTOCOMMIT的值来实现。其值为0表示关闭事务自动提交,值为1表示开启事务自动提交。修改、查看的语句如下:

# 查看当前会话的AUTOCOMMIT
SELECT @@AUTOCOMMIT# 关闭当前会话的事务自动提交
SET AUTOCOMMIT=0# 开启当前会话的事务自动提交
SET AUTOCOMMIT=1

三、事务保存点

在回滚事务时,事务内的所有操作都将被撤销。如果希望只撤销事务内的部分操作,则可以借助事务的保存点实现。在事务中设置保存点后,可以将事务回滚到指定的保存点。不用时也可以删除指定的保存点。相关语法:

# 创建保存点
SAVEPOINT name;# 回滚到指定保存点
ROLLBACK TO SAVEPOINT name;# 删除指定的保存点
RELEASE SAVEPOINT name;

一个事务可以创建多个保存点。
一旦提交事务,事务中的保存点都会被删除。
如果事务回滚到某个保存点后,该保存点之后创建的其他保存点也会被删除。

四、事务的隔离级别

MySQL支持多线程并发访问,用户可以通过不同的线程执行不同的事务。为保证多个事务之间互不影响,就需要为事务设置适当的隔离级别。
在MySQL中,事务有4种隔离级别,分别为READ UNCOMMITTED(读未提交)、READ COMMITTED(读已提交)、REPEATABLE READ(可重复读)和SERIALIZABLE(串行化)。
不同的事务隔离级别,可能存在不同的问题:

事务隔离级别脏读不可重复读幻读
读未提交YYY
读已提交-YY
可重复读--Y
串行化---

1. READ UNCOMMITTED

READ UNCOMMITTED是事务隔离级别中最低的级别,该级别下的所有事务可以读取其他事务中未提交的数据,这种读取方式也被称为脏读(Dirty Read)。在这种级别上,可能会产生很多问题,除非用户真的知道自己在做什么,并且有很好的理由选择这样做。本隔离级别很少应用于实际应用中。

设置事务的隔离级别

MySQL的默认隔离级别是REPEATABLE READ,该级别可以避免脏读。修改方式有两种:

  • 配置文件:修改mysql.ini配置文件,在最后加上事务隔离级别的配置即可全局修改事务隔离级别。
[mysqld]
transaction-isolation=REPEATABLE READ
# 这里全局修改为REPEATABLE READ级别,其实默认就是这个级别。
  • set session:针对当前session,可以使用set session命令修改。
# 将当前客户端中事务的隔离级别设置为READ UNCOMMITTED;
SET SESSION TRANSATION ISOLATION LEVEL READ UNCOMMITTED;

2. READ COMMITTED

在READ COMMITTED级别下,事务只能读取其他事务已经提交的内容,可以避免脏读现象,但是会出现不可重复读和幻读的情况。不可重复读是指在事务内重复读取别的线程已经提交的数据,由于多次查询期间,其他事务作了更新操作,因此出现多次读取的结果不一致的现象。
不可重复读并不算错误,但在有些情况下去不符合实际需求。

3. REPEATABLE READ

REPEATABLE READ是MySQL默认的事务隔离级别,它可以避免脏读、不可重复读。但在理论上,该级别会出现幻读。幻读又称为虚读,是指在一个事务内两次查询中的数据条数不一致。幻读和不可重复读类似 ,都是在两次查询过程中;不同的是,幻读是由于其他事务作了插入记录的操作,导致记录数有所增加。
MySQL的存储引擎通过多版本并发控制机制解决了该问题,当事务的隔离级别为REPEATABLE READ时可以避免幻读。

4. SERIALIZABLE

SERIALIZABLE是事务的最高隔离级别,它会在每个读的数据行上加锁,从而解决脏读、幻读、重复读的问题。这个级别可能导致大量的超时和锁竞争现象,因此也是性能最低的一种隔离级别。

五、MySQL的锁

在并发环境下,为了解决并发一致性问题保证事务的隔离性,MySQL采用了锁的机制。当一个事务在进行操作时会对操作的数据进行加锁,从而限制另一个事务的操作。为保证数据库的效率和性能,加锁的粒度不宜太大。

InnoDB的锁类型

MySQL的不同存储引擎采用的锁机制不完全相同。MyISAM存储引擎和Memory存储引擎采用表级锁,而InnoDB存储引擎既支持行级锁,也支持表级锁。

1. InnoDB的行级锁

InnoDB默认采用的是行级锁,并实现了以下两种类型的行级锁。

  • 共享锁(S)
    共享锁(Share Lock)也叫读锁。在同一个数据对象上可以有多把共享锁。如果一个事务在数据对象上加上了共享锁,则该事务可以读取数据但不能修改数据。其他的事务也可以在该数据对象上继续添加共享锁,也可以读取该数据,但同样也不能修改数据。
  • 排他锁(X)
    排他锁(Exclusive Lock)也叫写锁。在同一个数据对象上只允许有一把排他锁,获取到数据排他锁的事务可以读取数据和修改数据。一旦数据被加上了排他锁,其他事务就不允许再对该数据添加任何类型的行级锁。

查询语句SELECT默认不会添加任何锁类型。因此当数据上有了排他锁,还是可以通过查询语句SELECT获取数据的。
使用查询语句SELECT也可以为数据加锁。如:使用select ... fro update语句可以为数据添加排他锁;使用select ... lock in share mode语句可以为数据添加共享锁。

InnoDB的行锁是通过索引实现的,这意味着只有通过索引查询数据时,InnoDB引擎才会使用行级锁。否则,InnoDB存储引擎将使用表级锁。要注意的是等级锁不是针对表中的行加锁。如果表上没有对应的索引或者使用了相同的索引,也会造成锁的冲突进而导致整张表加上排他锁。

2. InnoDB的表级锁

InnoDB为了实现同时支持行级锁和表级锁,在其内部使用了两种类型的意向锁(Intention Locks)来实现多粒度锁机制。这两种意向锁都是表级锁。

  • 意向共享锁(IS)
    事务在给数据添加行级共享锁之前,必须先取得该表的意向共享锁。
  • 意向排他锁(IX)
    事务在给数据添加等级排他锁之前,必须先取得该表的意向排他锁。

由于意向锁是InnoDB存储引擎自动加的,不需要用户干预,是其内部使用的锁机制,因此对于普通用户来说不需要过多地关注这两种类型锁。

如果一个事务请求的锁模式与当前数据的锁模式兼容,InnoDB引擎就将事务请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待当前的锁释放。下表展示InnoDB引擎锁与锁之间的兼容模式。

事务请求的锁\事务已有的锁XIXSIS
X冲突冲突冲突冲突
IX冲突兼容冲突兼容
S冲突冲突兼容兼容
IS冲突兼容兼容兼容

死锁

死锁是指两个或两个以上事务在执行过程中,因为互相的等待或因为争抢相同的资源而造成的互相等待现象。
死锁的避免:

  • 以固定的顺序访问表和行。如两个任务批量更新的情形,简单方法是对id列表先排序后执行,这样就避免了交叉等待锁的情形。
  • 大事务拆小。大事务更倾向死锁,如果业务允许,将大事务拆小。
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
  • 降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择。
  • 为表添加合理的索引。

相关文章:

mysql笔记:15. 事务和锁

文章目录 一、事务概述二、事务基本操作三、事务保存点四、事务的隔离级别1. READ UNCOMMITTED设置事务的隔离级别 2. READ COMMITTED3. REPEATABLE READ4. SERIALIZABLE 五、MySQL的锁InnoDB的锁类型1. InnoDB的行级锁2. InnoDB的表级锁 死锁 在开发过程中,我们经常…...

Learn OpenGL 15 面剔除

面剔除 尝试在脑子中想象一个3D立方体,数数你从任意方向最多能同时看到几个面。如果你的想象力不是过于丰富了,你应该能得出最大的面数是3。你可以从任意位置和任意方向看向这个球体,但你永远不能看到3个以上的面。所以我们为什么要浪费时间…...

EndeavourOs(arch系)安装sunpinyin输入法(ibus) + 迅雷(xunlei-bin)

输入法 yay -S ibus yay -S ibus-libpinyin yay -S ibus-sunpinyin yay -Q ibus ibus-libpinyin ibus-sunpinyin #验证 # 注销然后打开ibus config... # 在Input Method 添加Chinese->SunPinYin # 使用Ctrl Space, 默认Super Space, 请自行修改 # 再次注销,开…...

Spring Cache框架的介绍和使用

Spring Cache spring cache是一个框架,实现类基于注解的缓存功能,只需要简单的加一个注解,就能实现缓存功能,大大简化我们在业务中操作缓存的代码。 spring cache只是提供了一层抽象,底层可以切换不同的cache实现&am…...

perl 用 XML::Parser 解析 XML文件,访问哈希

本篇我们会看到 Perl 成为知名编程语言的关键特色--哈希 hash(2000年以前叫:关联数组)。 在Perl 中,可以使用各种模块和函数来解析 XML元素和属性。其中,最古老的模块是 XML::Parser,它提供了一组完整的X…...

MATLAB中的矩阵和数组,它们之间有什么区别?

MATLAB中的矩阵和数组:概念、区别与联系 MATLAB(Matrix Laboratory,矩阵实验室)作为一款强大的数学软件,广泛应用于工程、科学、数学、计算机科学等领域。在MATLAB中,矩阵和数组是两个核心概念&#xff0c…...

python爬虫实战——抖音

目录 1、分析主页作品列表标签结构 2、进入作品页前 判断作品是视频作品还是图文作品 3、进入视频作品页面,获取视频 4、进入图文作品页面,获取图片 5、完整参考代码 6、获取全部作品的一种方法 本文主要使用 selenium.webdriver(Firef…...

Day1-力扣刷题学习打卡

1、两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以…...

C语言的位操作与位字段

C语言中的位操作允许程序员直接在整型变量的单个位或位组上进行操作。这种操作在许多低级编程任务中非常有用,尤其是在嵌入式系统编程中,如硬件操作、设备驱动及性能优化等场景。位操作主要使用以下几种位操作符: & (按位与&a…...

应用实战|从头开始开发记账本1:如何获取BaaS服务

本期视频开始,我们将通过一系列教程,来详细讲解MemFire Cloud BaaS服务的使用方法,通过这一系列的教程,你将学会如何只使用前端技术完成一个生产级应用的开发和上线。 以下是本期视频主要章节: BaaS服务介绍用户如何…...

el-form v-for循环列表的表单如何校验

1、普通的表单校验直接在最外层<el-form> :model"数据" :rules"规则" &#xff0c;再在<el-form-item>层设置prop值与model里数据定义的key保持一致即可。 <el-form-item label"名称" prop"ruleName" :rules"[{r…...

笔记:《NCT全国青少年编程能力等级测试教程Python语言编程三级》

NCT全国青少年编程能力等级测试教程Python语言编程三级 ISBN:9787302574859 绪论 专题1 序列和元组 考查方向 考点清单 考点1 组合数据类型 序列类型(字符串、列表、元组);集合类型;映射类型。 考点2 元组类型 (一)元组类型…...

地平线旭日x3派部署yolov5--全流程

地平线旭日x3派部署yolov5--全流程 前言一、深度学习环境安装二、安装docker三、部署3.1、安装工具链镜像3.2、配置天工开物OpenExplorer工具包3.3、创建深度学习虚拟空间&#xff0c;安装依赖&#xff1a;3.4、下载yolov5项目源码并运行3.5、pytorch的pt模型文件转onnx3.6、最…...

【Golang星辰图】Go语言云计算SDK全攻略:深入Go云存储SDK实践

Go语言云计算和存储SDK全面指南 前言 在当今数字化时代&#xff0c;云计算和存储服务扮演着至关重要的角色&#xff0c;为应用程序提供高效、可靠的基础设施支持。本文将介绍几种流行的Go语言SDK&#xff0c;帮助开发者与AWS、Google Cloud、Azure、MinIO、 阿里云和腾讯云等…...

深入理解TCP:序列号、确认号和自动ACK的艺术

深入理解TCP&#xff1a;序列号、确认号和自动ACK的艺术 在计算机网络的世界里&#xff0c;TCP&#xff08;传输控制协议&#xff09;扮演着至关重要的角色。它确保了数据在不可靠的网络环境中可靠地、按顺序地传输。TCP的设计充满智慧&#xff0c;其中序列号&#xff08;Seq&a…...

家电工厂5G智能制造数字孪生可视化平台,推进家电工业数字化转型

家电5G智能制造工厂数字孪生可视化平台&#xff0c;推进家电工业数字化转型。随着科技的飞速发展&#xff0c;家电行业正迎来一场前所未有的数字化转型。在这场制造业数字化转型中&#xff0c;家电5G智能制造工厂数字孪生可视化平台扮演着至关重要的角色。本文将从数字孪生技术…...

ctf_show笔记篇(web入门---代码审计)

301&#xff1a;多种方式进入 从index.php页面来看 只需要访问index.php时session[login]不为空就能访问 那么就在访问index.php的时候上传login 随机一个东西就能进去从checklogin页面来看sql注入没有任何过滤 直接联合绕过 密码随意 还有多种方式可以自己去看代码分析 30…...

c语言的字符串函数详解

文章目录 前言一、strlen求字符串长度的函数二、字符串拷贝函数strcpy三、链接或追加字符串函数strcat四、字符串比较函数strcmp五、长度受限制字符函数六、找字符串2在字符串1中第一次出现的位置函数strstr七、字符串切割函数strtok&#xff08;可以切割分隔符&#xff09;八、…...

HarmonyOS NEXT应用开发—折叠屏音乐播放器方案

介绍 本示例介绍使用ArkUI中的容器组件FolderStack在折叠屏设备中实现音乐播放器场景。 效果图预览 使用说明 播放器预加载了歌曲&#xff0c;支持播放、暂停、重新播放&#xff0c;在折叠屏上&#xff0c;支持横屏悬停态下的组件自适应动态变更。 实现思路 采用MVVM模式进…...

Java项目:55 springboot基于SpringBoot的在线视频教育平台的设计与实现015

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 在线视频教育平台分为管理员和用户、教师三个角色的权限模块。 管理员所能使用的功能主要有&#xff1a;首页、个人中心、用户管理、教师管理、课程信…...

说下你对TCP以及TCP三次握手四次挥手的理解?

参考自简单理解TCP三次握手四次挥手 什么是TCP协议&#xff1f; TCP( Transmission control protocol )即传输控制协议&#xff0c;是一种面向连接、可靠的数据传输协议&#xff0c;它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接&a…...

wsl-oracle 安装 omlutils

wsl-oracle 安装 omlutils 1. 安装 cmake 和 gcc-c2. 安装 omlutils3. 使用 omlutils 创建 onnx 模型 1. 安装 cmake 和 gcc-c sudo dnf install -y cmake gcc-c2. 安装 omlutils pip install omlutils-0.10.0-cp312-cp312-linux_x86_64.whl不需要安装 requirements.txt&…...

Python类属性和对象属性大揭秘!

​ 在Python中&#xff0c;对象和类紧密相连&#xff0c;它们各自拥有一些属性&#xff0c;这些属性在我们的编程中起着至关重要的作用。那么&#xff0c;什么是类属性和对象属性呢&#xff1f;别急&#xff0c;让我慢慢给你解释。 类属性 首先&#xff0c;类属性是定义在类本…...

北斗卫星在桥隧坡安全监测领域的应用及前景展望

北斗卫星在桥隧坡安全监测领域的应用及前景展望 北斗卫星系统是中国独立研发的卫星导航定位系统&#xff0c;具有全球覆盖、高精度定位和海量数据传输等优势。随着卫星导航技术的快速发展&#xff0c;北斗卫星在桥隧坡安全监测领域正发挥着重要的作用&#xff0c;并为相关领域…...

如何通过堡垒机JumpServer使用VisualCode 连接服务器进行开发

前言&#xff1a;应用场景 我们经常会碰到需要远程登录到内网服务器进行开发的场景&#xff0c;一般的做法都是通过VPN登录回局域网&#xff0c;然后配置ftp或者ssh使用开发工具链接到服务器上进行开发。如果没有出现问题&#xff0c;那么一切都正常&#xff0c;但到了出现问题…...

【Linux】进程优先级

&#x1f30e;进程的优先级 文章目录&#xff1a; 进程状态 优先级相关       什么是优先级       为什么要有优先级       进程的优先级 调整进程优先级       调整优先级       优先级极限测试 Linux的调度与切换 总结 前言&#xff1a; 进程…...

Fair Data Exchange:区块链实现的原子式公平数据交换

1. 引言 2024年斯坦福大学和a16z crypto research团队 论文 Atomic and Fair Data Exchange via Blockchain 中&#xff0c;概述了一种构建&#xff08;包含过期EIP-4844 blobs的&#xff09;fair data-markets的协议。该论文源自a16z crypto的暑期实习计划&#xff0c;与四名…...

详解优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器

代码示例在最后。 认识一下ThreadPoolTaskExecutor org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor这是由Sping封装的加强版线程池&#xff0c;其实是Spring使用装饰者模式对ThreadPoolExecutor进一步优化。 它不仅拥有ThreadPoolExecutor所有的核心参数…...

Vue3+TS+Vite 找不到模块“@/components/xxx/xxx”或其相应的类型声明

引入vue文件时文件是存在的&#xff0c;引入路径也是对的&#xff0c;报找不到模块&#xff0c;有一些解决方案是在tsconfig.json里面做一些配置&#xff0c;大家可以自行百度&#xff08;不知道是不是我百度的不对&#xff0c;我的没有解决&#xff09;还有一种是在项目根目录…...

Vue3-响应式基础:单文件和组合式文件

单文件&#xff1a;html <!DOCTYPE html> <html> <head><title>响应式基础</title> </head> <body><div id"app" ><!-- dynamic parameter:同样在指令参数上也可以使用一个 JavaScript 表达式&#xff0c;需要包…...