【MySQL | 第五篇】MySQL事务总结

news2024/11/25 20:37:37

在这里插入图片描述

文章目录

  • 5.MySQL事务
    • 5.1什么是事务?
    • 5.2什么是数据库事务?
    • 5.3数据库事务四大特性
    • 5.4并发事务带来的问题及解决方案?
      • 5.4.1脏读/不可重复读/幻读
      • 5.4.2不可重复读和幻读有什么区别?
      • 5.4.3解决并发事务带来的问题
        • (1)锁
        • (2)MVCC
    • 5.5四大隔离级别
      • 5.5.1隔离级别介绍
      • 5.5.2MySQL的隔离级别是基于锁实现的吗?
    • 5.6MySQL锁
      • 5.6.1表级锁VS行级锁
      • 5.6.2使用行级锁的注意事项
      • 5.6.3 InnoDB行锁类型
      • 5.6.4 共享锁VS排他锁
      • 5.6.5意向锁
      • 5.6.6 当前读和快照读有什么区别?
        • (1)快照读
        • (2)当前读
    • 5.7总结

5.MySQL事务

5.1什么是事务?

定义:事务是逻辑上的一组操作,要么都执行,要么都不执行。

例子(转账):假如小明要给小红转账 1000 元,这个转账会涉及到两个关键操作,这两个操作必须都成功或者都失败。

  1. 将小明的余额减少 1000 元
  2. 将小红的余额增加 1000 元。

事务会把这两个操作就可以看成逻辑上的一个整体,这个整体包含的操作要么都成功,要么都要失败。这样就不会出现小明余额减少而小红的余额却并没有增加的情况。

image-20240319191757612

5.2什么是数据库事务?

数据库事务 (transaction)是 访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。 事务由事务开始与事务结束之间执行的全部数据库操作组成。

  • 作用:

数据库事务可以保证多个对数据库的操作(也就是 SQL 语句)构成一个逻辑上的整体。构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行

5.3数据库事务四大特性

image-20240319191721013

  1. 原子性Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  2. 一致性Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. 隔离性Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
  4. 持久性Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响

只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!

5.4并发事务带来的问题及解决方案?

5.4.1脏读/不可重复读/幻读

  • 脏读:一个事务读取到了另一个事务还未提交的数据,后面另一个事务又将该数据回滚,那么这个事务读取到的数据就是脏的

脏读

  • 不可重复读:一个事务内多次读取同一数据,但是数据不一样。如图,事务2两次读取事务的过程中,事务1读取并修改数据,导致不可重复读问题

不可重复读

  • 幻读:一个事务读取了几行数据,接着另一个并发事务插入一些数据,随后第一个事务再进行查询发现多了一些原本不存在的记录

幻读

5.4.2不可重复读和幻读有什么区别?

  • 不可重复读的重点:内容修改,比如多次读取一条记录发现其中某些记录的值被修改;
  • 幻读的重点:记录新增,比如多次执行同一条查询语句(DQL)时,发现查到的记录增加了。

幻读其实可以看作是不可重复读的一种特殊情况,单独把区分幻读的原因主要是解决幻读和不可重复读的方案不一样

5.4.3解决并发事务带来的问题

  1. MySQL 中并发事务的控制方式无非就两种:MVCC
    1. 锁可以看作是悲观控制的模式
    2. 多版本并发控制(MVCC,Multiversion concurrency control)可以看作是乐观控制的模式。
(1)锁
  1. 控制方式下会通过锁来显示控制共享资源而不是通过调度手段,MySQL 中主要是通过 读写锁实现并发控制

    1. 共享锁(S 锁):又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。

    2. 排他锁(X 锁):又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条记录加任何类型的锁(锁不兼容)。

  2. 根据根据锁粒度的不同,又被分为 表级锁(table-level locking)行级锁(row-level locking)

    1. InnoDB 不光支持表级锁,还支持行级锁,默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁)
(2)MVCC
  1. MVCC多版本并发控制方法,即对一份数据会存储多个版本,通过事务的可见性来保证事务能看到自己应该看到的版本。通常会有一个全局的版本分配器来为每一行数据设置版本号,版本号是唯一的。
  2. MVCC 在 MySQL 中实现所依赖的手段主要是: 隐藏字段、read view、undo log
    • undo log : undo log 用于记录某行数据的多个版本的数据
    • read view 和 隐藏字段 : 用来判断当前版本数据的可见性。

5.5四大隔离级别

5.5.1隔离级别介绍

  • READ-UNCOMMITTED(读取未提交)
    • 最低的隔离级别
    • 允许读取尚未提交的数据变更
    • 可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读取已提交)
    • 允许读取并发事务已经提交的数据
    • 可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读)
    • 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。原因:不能读取别的事务修改的数据,但是还可以读取别的事务新增的几行数据,所以还会发送幻读
    • 可以阻止脏读和不可重复读,但仍有可能发生幻读。(默认隔离级别)
  • SERIALIZABLE(可串行化)
    • 最高的隔离级别,完全服从 ACID 的隔离级别。
    • 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,
    • 也就是说,该级别可以防止脏读、不可重复读以及幻读。

5.5.2MySQL的隔离级别是基于锁实现的吗?

  1. MySQL 的隔离级别基于锁和 MVCC 机制共同实现的。
  2. SERIALIZABLE 隔离级别是通过锁来实现的READ-COMMITTED 和 REPEATABLE-READ 隔离级别是基于 MVCC 实现的。不过, SERIALIZABLE 之外的其他隔离级别可能也需要用到锁机制,就比如 REPEATABLE-READ 在当前读情况下需要使用加锁读来保证不会出现幻读

5.6MySQL锁

在MySQL中,锁是一种常见的并发事务的控制方式。

5.6.1表级锁VS行级锁

  • 表级锁:
    • MySQL 中锁定粒度最大的一种锁(全局锁除外)
    • 针对非索引字段加的锁,对当前操作的整张表加锁,实现简单
    • 资源消耗也比较少,加锁快,不会出现死锁
    • 不过,触发锁冲突的概率最高,高并发下效率极低。
    • 表级锁和存储引擎无关
    • MyISAM 和 InnoDB 引擎都支持表级锁。
  • 行级锁:
    • MySQL 中锁定粒度最小的一种锁
    • 针对索引字段加的锁 ,只针对当前操作的行记录进行加锁
    • 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,
    • 但加锁的开销也最大,加锁慢,会出现死锁
    • 行级锁和存储引擎有关,是在存储引擎层面实现的

5.6.2使用行级锁的注意事项

InnoDB 的行锁是针对索引字段加的锁

表级锁是针对非索引字段加的锁

当我们执行 UPDATEDELETE 语句时,如果 WHERE条件中字段没有命中唯一索引或者索引失效的话,就会导致扫描全表对表中的所有行记录进行加锁。这个在我们日常工作开发中经常会遇到,一定要多多注意!!!

5.6.3 InnoDB行锁类型

InnoDB 行锁是通过对索引数据页上的记录加锁实现的,MySQL InnoDB 支持三种行锁定方式:

  • 记录锁(Record Lock):也被称为记录锁,属于单个行记录上的锁。
  • 间隙锁(Gap Lock):锁定一个范围,不包括记录本身。
  • 临键锁(Next-Key Lock):Record Lock+Gap Lock,锁定一个范围,包含记录本身,主要目的是为了解决幻读问题(MySQL 事务部分提到过)。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。

在 InnoDB 默认的隔离级别 REPEATABLE-READ 下,行锁默认使用的是 Next-Key Lock。但是,如果操作的索引是唯一索引或主键,InnoDB 会对 Next-Key Lock 进行优化,将其降级为 Record Lock,即仅锁住索引本身,而不是范围。

5.6.4 共享锁VS排他锁

不论是表级锁还是行级锁,都存在共享锁(Share Lock,S 锁)和排他锁(Exclusive Lock,X 锁)这两类:

  • 共享锁(S 锁):又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。
  • 排他锁(X 锁):又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条事务加任何类型的锁(锁不兼容)。

排他锁与任何的锁都不兼容,共享锁仅和共享锁兼容。

由于 MVCC 的存在,对于一般的 SELECT 语句,InnoDB 不会加任何锁。不过可以通过以下语句显式加共享锁或排他锁。

# 共享锁 可以在 MySQL 5.7 和 MySQL 8.0 中使用
SELECT ... LOCK IN SHARE MODE;
# 共享锁 可以在 MySQL 8.0 中使用
SELECT ... FOR SHARE;
# 排他锁
SELECT ... FOR UPDATE;

5.6.5意向锁

问题:如果需要用到表锁的话,如何判断表中的记录没有行锁呢,一行一行遍历肯定是不行,性能太差。我们需要用到一个叫做意向锁的东东来快速判断是否可以对某个表使用表锁

意向锁是表级锁,共有两种:

  • 意向共享锁(Intention Shared Lock,IS 锁)
    • 事务有意向对表中的某些记录加共享锁(S 锁)
    • 加共享锁前必须先取得该表的 IS 锁
  • 意向排他锁(Intention Exclusive Lock,IX 锁)
    • 事务有意向对表中的某些记录加排他锁(X 锁)
    • 加排他锁之前必须先取得该表的 IX 锁。

意向锁是由数据引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享/排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。

注意:意向锁之间是互相兼容的。

IS 锁IX 锁
IS 锁兼容兼容
IX 锁兼容兼容

意向锁和共享锁和排它锁互斥(这里指的是表级别的共享锁和排他锁,意向锁不会与行级的共享锁和排他锁互斥)。

IS 锁IX 锁
S 锁兼容互斥
X 锁互斥互斥

5.6.6 当前读和快照读有什么区别?

(1)快照读
  1. 快照即记录的历史版本,每行记录可能存在多个历史版本(多版本技术)。
  2. 快照读的情况下,如果读取的记录正在执行 UPDATE/DELETE 操作,读取操作不会因此去等待记录上 X 锁的释放,而是==会去读取行的一个快照==。

快照读(一致性非锁定读)就是单纯的 SELECT 语句,但不包括下面这两类 SELECT 语句:

SELECT ... FOR UPDATE

# 共享锁 可以在 MySQL 5.7 和 MySQL 8.0 中使用
SELECT ... LOCK IN SHARE MODE;

# 共享锁 可以在 MySQL 8.0 中使用
SELECT ... FOR SHARE;

只有在事务隔离级别 RC(读取已提交) 和 RR(可重读)下,InnoDB 才会使用一致性非锁定读:

  • 在 RC 级别下,对于快照数据,一致性非锁定读总是读取被锁定行的最新一份快照数据
  • 在 RR 级别下,对于快照数据,一致性非锁定读总是读取本事务开始时的行数据版本

快照读比较适合对于数据一致性要求不是特别高且追求极致性能的业务场景。

(2)当前读

当前读 (一致性锁定读)就是给行记录加 X 锁或 S 锁

当前读的一些常见 SQL 语句类型如下:

# 对读的记录加一个X锁
SELECT...FOR UPDATE
# 对读的记录加一个S锁
SELECT...LOCK IN SHARE MODE
# 对读的记录加一个S锁
SELECT...FOR SHARE
# 对修改的记录加一个X锁
INSERT...
UPDATE...
DELETE...

5.7总结

MySQL事务总结篇介绍了事务、数据库事务的定义、四大特性(ACID)、并发事务带来的问题(脏读/不可重复读/幻读)及解决方法(锁/MVCC),以及四大隔离级别(读未提交、读已提交、可重复读、串行化);再详细介绍了MySQL锁(表级锁/行级锁、共享锁/排他锁、意向锁、当前读/快照读)

在这里插入图片描述

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

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

相关文章

windows服务器iis更换彻底删除 原443 ssl证书以及一个服务器运行多个独立域名网站并绑定多个证书的方法

服务器上的433 ssl证书,可以让网站以https加密方式访问,但是这个证书会占用443端口,iis7版本,只能安装一个443证书,所以.原来的过期了.需要删除.删除方式,不是进运行 winr的mmc 而是进iis的默认的总的主页面板(不是点击具体的网站或者程序池),点击服务器证书.进去才能删除.否则…

5G网络架构及技术(一):入门级介绍

参考资料: [1] 5G网络架构,March 15, 2020 / By Adnan Ghayas [2] 5G应用场景,June 2, 2021 / By Adnan Ghayas [3] 独立和非独立5G网络,September 19, 2020 / By Adnan Ghayas 5G网络架构(一):…

人类与AI:谁做出最好的决定?

此为看完视频Humans vs. AI: who makes the best decisions?后的笔记。 对于不同的任务,AI和人类各有擅长。 在本视频中,作者具化到了一个欺诈检测系统。欺诈检测系统会生成潜在欺诈交易的警报,金融分析师会审查每个警报。但每天都会生成数…

Javascript的Execution Context

概要 本文主要通过一个实例,来理解什么是Javascript中的Execution Context,以及在JavaScript执行过程中,Execution Context是如何工作的。 基本概念 事实上,我们可以理解为JavaScript代码在一个盒子中执行,而这个盒…

IDC:2027年中国网络安全市场规模将超200亿美元

IDC于近日发布了2024年V1版IDC《全球网络安全支出指南》(IDC Worldwide Security Spending Guide)。IDC数据显示,2022年全球网络安全IT总投资规模为1890.1亿美元,并有望在2027年增至3288.8亿美元,五年复合增长率(CAGR)…

阅读笔记(CVPR2020)Warping Residual Based Image Stitching for Large Parallax

基于变形残差的大视差图像拼接 K. -Y. Lee and J. -Y. Sim, "Warping Residual Based Image Stitching for Large Parallax," 2020 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), Seattle, WA, USA, 2020, pp. 8195-8203, doi: 10.1109/…

重学SpringBoot3-函数式Web

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-函数式Web 函数式Web编程简介RouterFunctionRequestPredicateServerRequestServerResponse 好处示例结论 随着响应式编程范式的兴起和 Java 函数式编程能…

回来了,你瞧不上的中文编程

谈及中文编程,我们无法绕过一个开创性的里程碑——“易语言”。这款编程语言以“易”为核心理念,独树一帜地采用全中文支持,不仅显著降低了编程的门槛,更承载了无数人的“民族语言编程梦想”。 回溯到21世纪初的2000年9月&#xf…

详细分析Js中的Promise.all基本知识(附Demo)

目录 1. 基本知识2. Demo3. 实战 1. 基本知识 Promise.all 是 JavaScript 中的一个方法,它接受一个由 Promise 对象组成的数组作为参数,并在所有 Promise 对象都变为 resolved(已完成)状态时才返回一个新的 Promise 对象&#xf…

扫码收集用户数据怎么做?创建问卷表单二维码的方法

现在通过扫描二维码的方式来收集用户数据,比如制作问卷、签到表、信息登记等类型都可以通过生成表单二维码的形式来做数据采集。现在大部分都习惯通过二维码来获取内容,所以扫码填表的方式更符合现在人的生活习惯,有利于快速收集用户数据&…

51单片机-蜂鸣器

1.蜂鸣器的介绍 无源蜂鸣器不能一直通电&#xff0c;无源蜂鸣器内部的线圈较小&#xff0c;易烧坏 蜂鸣器的驱动 达林顿晶体管&#xff08;npn型&#xff09; 应用&#xff1a; 按下独立按键同时蜂鸣器响起提示音&#xff0c;数码管显示对应的独立按键键码 #include <REG…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——差分进化算法(DE)

基于python语言&#xff0c;采用经典差分进化算法&#xff08;DE&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成…

ATG-2081功率信号源在电子实验中的应用

功率信号源被广泛应用于电子实验领域&#xff0c;主要用于产生精确、干净的高频信号。这些信号可以被用于测试各种电子器件和电路&#xff0c;例如射频、微波电路和天线等。下面将介绍功率信号源在电子实验中的应用。 功率信号源可以产生稳定、高质量的RF和微波信号&#xff0c…

OpenGL-高斯模糊原理

OpenGL-高斯模糊原理 正态分布 上图人类的智商分布比例&#xff0c;大多数人的智商集中在85-115&#xff0c;超高和超低智商的人只占很小的比例&#xff0c;柱状图可用一条曲线拟合&#xff0c;如图中红色曲线所示. 这个钟形曲线就是正态分布曲线. 正态分布曲线体现了宇宙中很…

针对BSV区块链新推出的网络访问规则NAR和警报系统AS的解释与问答

​​发表时间&#xff1a;2024年2月22日 BSV区块链社区团队最近开设了一个Twitter&#xff08;X&#xff09;话题空间&#xff0c;讨论BSV区块链协会最新推出的网络访问规则和警报系统的相关问题。 本次讨论由BSV区块链社区负责人Brett Banfe主持&#xff0c;以便社区成员更好…

JAVA八股--基础--下

JAVA八股--基础--下 从字节码层面看try-catch-finally的实现机制为什么要用泛型&#xff1f; | 泛型方法、通配符该如何使用 | Java中的泛型知识反射 何为反射 反射优缺点 应用场景&#xff08;需要先学习相关基础知识&#xff09;SPI机制I/O 流为什么要分为字节流和字符流呢?…

如何利用IP地址分析风险和保障网络安全

随着网络攻击的不断增加和演变&#xff0c;保障网络安全已经成为了企业和组织不可忽视的重要任务。在这样的背景下&#xff0c;利用IP地址分析风险和建立IP风险画像标签成为了一种有效的手段。本文将深入探讨IP风险画像标签的作用以及如何利用它来保障网络安全。 IP风险画像查…

用Compute Shader处理图像数据后在安卓机上不能正常显示渲染纹理

1&#xff09;用Compute Shader处理图像数据后在安卓机上不能正常显示渲染纹理 2&#xff09;折叠屏适配问题 3&#xff09;Prefab对DLL中脚本的引用丢失 4&#xff09;如何优化Unity VolumeManager中的ReplaceData 这是第378篇UWA技术知识分享的推送&#xff0c;精选了UWA社区…

数据库基本介绍及编译安装mysql

目录 数据库介绍 数据库类型 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统 DBMS的工作模式 关系型数据库的优缺点 编译安装mysql 数据库介绍 数据&#xff1a;描述事物的的符号纪录称为数据&#xff08;Data&#xff09; 表&#xff1a;以行和列的形式组成…

个人商城系统开源(配置支付宝支付2)

原文地址&#xff1a;个人商城系统开源&#xff08;配置支付宝支付2&#xff09; - Pleasure的博客 下面是正文内容&#xff1a; 前言 在上一篇文章中我曾提到过关于网站支付宝支付的方法&#xff0c;接下来我们来介绍第二种。 个人博客地址&#xff1a;个人商城系统开源&…