MySQL事务篇1:事物的四大特性(ACID)、三类数据读取问题与隔离级别

一、什么是事务?

        MySQL的事务(Transaction)是一组由数据库管理系统(DBMS)执行的一个或多个SQL语句的集合,这些SQL语句作为一个单独的工作单元执行。事务的主要目的是确保数据库的一致性和完整性,特别是在并发环境下。这些操作要么全部都执行,要么都不执行, 它是一个不可分割的工作执行单元。

二、事务的特性

        事务是由[MySQL 的引擎]来实现的,我们常见的 InnoDB 引擎它是支持事务的。不过并不是所有的引擎都能支持事务,比如 MySQL 原生的 MyISAM 引擎就不支持事务,也正是这样,所以大多数 MySQL 的引擎都是用 InnoDB。
        事务有四个关键特性,通常被称为ACID特性。这四个特性是:

1、原子性(Atomicity):
        事务中的所有操作要么全部成功,要么全部失败。即事务是一个不可分割的工作单元。即使在事务执行过程中发生了错误,事务中的任何更改都不会保留,系统会回滚(Undo)所有已经执行的操作,使数据库回到事务开始之前的状态。

2、一致性(Consistency)
        事务从一个一致的数据库状态转换到另一个一致的数据库状态。数据库在事务开始之前和结束之后都必须满足所有的定义的约束、触发器和规则。换句话说,事务开始前和事务结束后数据应该是一致的,例如张三有300,李四有400,那么无论他们如何转账,总钱数700应该是不变的

3、隔离性(Isolation)
        事务的执行过程对其他事务是隔离的。即使多个事务并发执行,每个事务也无法看到其他事务未提交的中间状态,即多个并发事务直接要相互隔离,互不干扰。隔离性保证了并发事务的正确执行。MySQL提供了不同的隔离级别来控制事务之间的隔离程度,包括未提交读、提已交读、可重复读和可序列化。

4、持久性(Durability)
        一旦事务提交,所做的更改将永久保存到数据库中,即使发生系统故障,数据也不会丢失。持久性通过将事务的日志记录到持久存储设备(如磁盘)上来实现。提交事务后,系统保证即使系统崩溃,也能通过日志恢复已提交的数据。

InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?

  • 持久性是通过 redo log (重做日志)来保证的;
  • 原子性是通过 undo log(回滚日志) 来保证的;
  • 隔离性是通过 MVCC(多版本并发控制)或锁机制来保证的;
  • 一致性则是通过持久性+原子性+隔离性来保证;

简单知道一下即可,这是一个非常复杂的底层逻辑。

三、并发事务下三类数据读取问题与数据更新

       MySQL 服务端是允许多个客户端连接的,这意味着 MySQL 会出现同时处理多个事务的情况。主要有三类数据读取问题:

1、脏读(Dirty Read):
        一个事务能够读取另一个事务尚未提交的数据。这种情况会导致读取的数据可能在未来被回滚,从而导致读取到不正确的数据。
 示例:事务A更新了某行数据,然后事务B读取了这些更新的数据。然而,事务A随后回滚了,这意味着事务B读到了未提交的、随后被撤销的数据。

2、不可重复读(Non-Repeatable Read):

        一个事务在读取某行数据后,再次读取该行数据时,发现数据已经被另一个已提交的事务修改了两次读取同一数据的结果不一致

示例:事务A在某时刻读取了一行数据。然后事务B更新了这行数据并提交。事务A再次读取该行数据时,发现数据已经改变。

3、幻读(Phantom Read):

        一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”。

示例:事务A读取了满足某个条件的所有数据行。事务B插入了一些满足这个条件的新数据行并提交。事务A再次读取时,发现多了一些之前没有的数据行。

        我们对三类数据读取问题做一个总结就是:

脏读:读到其他事务未提交的数据;

不可重复读:前后读取的数据不一致;

幻读:前后读取的记录数量不一致。

        在并发事务下,不仅会遇到数据读取问题,还会遇到数据更新问题,主要有以下两类:

丢失更新(Lost Update)

        两个事务都读取同一数据并修改它们中的一个,导致一个事务的修改被另一个事务的修改覆盖,最终的更新丢失。这种情况通常发生在没有合适的锁机制来同步并发事务时。

示例:事务A和事务B都读取了同一行数据,然后事务A和事务B都修改了这行数据并提交。事务A的修改被事务B的修改覆盖,导致事务A的更新丢失。

不可重复写(Non-Repeatable Write)

        一个事务在写入某行数据后,另一个事务修改了这行数据。当第一个事务再次写入这行数据时,发现数据已经被另一个事务改变了。这种情况导致数据的不一致性。

示例:事务A和事务B同时读取同一行数据。事务A先修改了数据并提交,事务B再修改数据并提交,事务A的更改可能没有被考虑在内。

四、事务隔离级别

前面我们提到,当多个事务并发执行时可能会遇到【脏读、不可重复读、幻读】的现象,这些现象会对事务的一致性产生不同程序的影响。SQL 标准提出了四种隔离级别来规避这些现象,隔离级别越高,性能效率就越低,这四个隔离级别如下:

  • 读未提交:指一个事务还没提交时,它做的变更就能被其他事务看到。
  • 读提交:指一个事务提交之后,它做的变更才能被其他事务看到。
  • 可重复读:指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别。
  • 串行化:会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

        不同的数据库厂商对 SQL 标准中规定的 4 种隔离级别的支持不一样,有的数据库只实现了其中几种隔离级别,MySQL 虽然支持 4 种隔离级别,但是与SQL 标准中规定的各级隔离级别允许发生的现象却有些出入。(隔离级别的定义由SQL提出,这不是MySQL规定的)
        MySQL InnoDB 引擎在可重复读隔离级别下,可以很大程度上避免幻读现象的发生,所以 MySQL 并不会使用串行化隔离级别来避免幻读现象的发生,因为使用串行化隔离级别会严重影响性能(毕竟是悲观锁)。而关于为什么可以很大程度上避免幻读现象的发生,这就是涉及到了一个概念叫做MVCC。

        多版本并发控制(MVCC,Multi-Version Concurrency Control)是一种用于提高数据库系统并发性能的技术。它允许多个事务在不加锁的情况下并发读取和写入数据,从而避免了许多锁竞争问题。MVCC通过保存数据的多个版本来实现一致性和隔离性。关于更多MVCC的东西可以看我的另一篇文章。 

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

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

相关文章

leecode 637 二叉树的层平均值

leetcode 二叉树相关-层序遍历专题 二叉树的层序遍历一般来说,我们是利用队列来实现的,先把根节点入队,然后在出队后将其对应的子节点入队,然后往复此种操作。相比于二叉树的遍历递归,层序遍历比较简单,有…

CHI协议_1

作者:someone链接:https://www.zhihu.com/question/304259901/answer/3455648666来源。 1. AMBA CHI简介 一致性总线接口(CHI)是AXI一致性扩展(ACE)协议的演进。它是Arm的AMBA总线的一部分。AMBA是一种免…

美团Java社招面试题真题,最新面试题

如何处理Java中的内存泄露? 1、识别泄露: 使用内存分析工具(如Eclipse Memory Analyzer Tool、VisualVM)来识别内存泄露的源头。 2、代码审查: 定期进行代码审查,关注静态集合类属性和监听器注册等常见内…

.NET File Upload

VS2022 .NET8 &#x1f4be;基础上传示例 view {ViewData["Title"] "File Upload"; }<h1>ViewData["Title"]</h1><form method"post" enctype"multipart/form-data" action"/Home/UploadFile"…

Android 系统日志(Log) JNI实现流程源码分析

1、JNI概述 Java Native Interface (JNI) 是一种编程框架&#xff0c;使得Java代码能够与用其他编程语言&#xff08;如C和C&#xff09;编写的本地代码进行交互。JNI允许Java代码调用本地代码的函数&#xff0c;也允许本地代码调用Java代码的函数。下面是对JNI机制的详细概述…

【单片机】STM32F070F6P6 开发指南(一)STM32建立HAL工程

文章目录 一、基础入门二、工程初步建立三、HSE 和 LSE 时钟源设置四、时钟系统&#xff08;时钟树&#xff09;配置五、GPIO 功能引脚配置六、配置 Debug 选项七、生成工程源码八、生成工程源码九、用户程序下载 一、基础入门 f0 pack下载&#xff1a; https://www.keil.arm…

大模型应用:基于Golang实现GPT模型API调用

1.背景 当前OpenAI提供了开放接口&#xff0c;支持通过api的方式调用LLM进行文本推理、图片生成等能力&#xff0c;但目前官方只提供了Python SDK。为了后续更方便集成和应用&#xff0c;可以采用Golang对核心推理调用接口进行封装&#xff0c;提供模型调用能力。 2.相关准备…

Spark运行模式详解

Spark概述 Spark 可以在多种不同的运行模式下执行&#xff0c;每种模式都有其自身的特点和适用场景。 部署Spark集群大体上分为两种模式&#xff1a;单机模式与集群模式。大多数分布式框架都支持单机模式&#xff0c;方便开发者调试框架的运行环境。但是在生产环境中&#xff…

软件web化的趋势

引言 在信息技术飞速发展的今天&#xff0c;软件Web化已成为一个不可忽视的趋势。所谓软件Web化&#xff0c;即将传统的桌面应用软件转变为基于Web的应用程序&#xff0c;使用户能够通过浏览器进行访问和使用。传统软件通常需要在用户的计算机上进行安装和运行&#xff0c;而W…

Cadence OrCAD学习笔记(3)capture使用技巧_1

本期介绍capture的一些使用技巧。资料来源于小破站up主硬小二 1、导出像Visio规格的图纸 2、全局修改元件属性 然后保存、关闭即可。 3、导出BOM 4、导出网表 5、元件自动编号 6、capture软件和allegro关联 7、新建原理图symbol 以上为添加封装库的路径 如果要创建多部分的sy…

神器EasyRecovery2024中文电脑版下载!让数据恢复不再难

在数字化时代&#xff0c;数据就是我们的财富。无论是重要的工作报告&#xff0c;还是那些珍贵的生活瞬间照片&#xff0c;或是我们与朋友间的聊天记录&#xff0c;都储存在我们的电脑或手机中。然而&#xff0c;有时候&#xff0c;意外总是突如其来&#xff0c;电脑突然崩溃&a…

C++Qt操作Lotus Domino数据库 Lotus Domino C++连接Lotus Domino C++快速开发Lotus Domino

java连接domino C#连接domino python连接domino go连接domino,delphi连接domino Excel连接domino Flutter、微信小程序连接domino C 操作 Lotus Domino 数据库&#xff1a;自动化与效率的结合 引言 在企业级应用中&#xff0c;Lotus Domino 提供了一个强大的协作平台&#xff0…

【Linux】TCP协议【下一】{三次握手/四次挥手的深度解读==状态变化}

文章目录 本篇知识需要有TCP协议【中】的知识&#xff01;详情点击&#x1f447;1.测试一&#xff1a;服务器start函数不定义任何行为&#xff08;不调用accept&#xff09;的三次握手状态变化int listen(int sockfd, int backlog);的backlog参数全连接队列当全连接队列已满&am…

BGP策略实验(路径属性和选路规则)

要求&#xff1a; 1、使用preval策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2、使用AS Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3、配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4、使用Local Preference策略&#xff0c;确保R1通过R2到达19…

Python轻松玩转excel操作指导

目录 一、一图概览 二、表格操作 三、内容操作 四、单元格操作 五、Pandas实现表格操作 六、常见场景示例 一、一图概览 ​ ​本文主要对openpyxl库的常用表格操作进行了梳理&#xff0c;熟练的运用后可极大地提升工作效率。 二、表格操作 #创建一个表格sheet.xlsx #…

C++编程揭秘:虚表机制与ABI兼容性的实例剖析

前言&#xff1a; 假设你的应用程序引用的一个库某天更新了&#xff0c;虽然 API 和调用方式基本没变&#xff0c;但你需要重新编译你的应用程序才能使用这个库&#xff0c;那么一般说这个库是源码兼容&#xff08;Source compatible&#xff09;&#xff1b;反之&#xff0c;如…

C语言指针相关知识(第五篇章)(非常详细版)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、sizeof和strlen对比二、数组之间的比较&#xff08;依据strlen和sizeof来呈现&#xff09;&#xff08;一&#xff09;、一维整型数组&#xff08;二&#…

Value-Based Reinforcement Learning(2)

Temporal Difference &#xff08;TD&#xff09; Learning 上节已经提到了如果我们有DQN&#xff0c;那么agent就知道每一步动作如何做了&#xff0c;那么DQN如何训练那&#xff1f;这里面使用TD算法。 简略分析&#xff1a; 是的估计 是的估计 所以&#xff1a; Deep Re…

对vue3/core源码ref.ts文件API的认识过程

对toRef()API的认识的过程: 最开始认识toRef()是从vue3源码中的ref.ts看见的,右侧GPT已经举了例子 然后根据例子,在控制台输出ref对象是什么样子的: 这就是ref对象了,我们根据对象中有没有__v_isRef来判断是不是一个ref对象,当对象存在且__v_isRef true的时候他就判定为是一个…

Linux-组管理和权限管理

1 Liunx组的基本介绍&#xff1a; 在Linux中的每个用户必须属于一个组&#xff0c;不能独立于组外。在Linux中每个文件都有所有者、所在组、其他组的概念 所有者所在组其它组改变用户所在的组 2 文件/目录的所有者 一般文件的创建者&#xff0c;谁创建了该文件&#xff0c;就…