数据库事务的超级详细讲解,包括事务特性、事务隔离级别、MVCC(多版本并发控制)

数据库事务:

主要有事务特性,事务的隔离级别,MVCC。

事务特性:

事务(Transaction)是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全部成功执行,要么全部不执行,不能出现部分执行的情况。事务具有以下四个特性,通常缩写为ACID:

1、原子性(Atomicity):事务是一个不可分割的工作单位,要么全部执行,要么全部不执行。如果事务中的任何一步操作失败,整个事务都会被回滚(Rollback),回到操作之前的状态,不会造成数据的损坏或不一致。

2、一致性(Consistency):事务在执行前后,数据库从一个一致性状态转移到另一个一致性状态。即使在事务执行过程中出现异常,数据库也会通过回滚操作,将数据恢复到一致性状态。

3、隔离性(Isolation):事务的执行不会受到其他事务的影响,每个事务在执行过程中都应该感觉不到其他事务的存在。即使多个事务同时操作同一数据,也不会互相干扰。隔离性能够防止并发事务导致的数据异常和不一致问题。

4、持久性(Durability):一旦事务被提交(Commit),其所做的修改将会永久保存在数据库中,并且即使系统发生故障,这些修改也不会丢失。数据库系统会将事务的修改持久化到磁盘中,以保证数据的持久性。

案例说明事务的特性:

假设有一个银行系统,用户 A 和用户 B 分别有 1000 元和 2000 元存款。用户 A 想要向用户 B 转账 500 元。这个转账操作可以通过以下 SQL 语句来实现:

sqlCopy Code-- 开启事务
START TRANSACTION;-- 扣除用户 A 的账户余额
UPDATE accounts SET balance = balance - 500 WHERE user_id = 'A';-- 增加用户 B 的账户余额
UPDATE accounts SET balance = balance + 500 WHERE user_id = 'B';-- 提交事务
COMMIT;

以上 SQL 语句实现了转账操作的原子性。如果在转账过程中发生了异常,比如数据库连接断开或者用户 A 的余额不足,那么整个事务都会被回滚,用户 A 和用户 B 的账户余额都会恢复到转账前的状态,确保了事务的一致性和持久性。

此外,隔离性的特点可以保证即使有其他用户同时查询用户 A 和用户 B 的账户余额,也不会受到转账操作的影响,保证了数据的隔离性。

隔离级别:

数据库事务的隔离级别定义了事务在并发执行时,系统如何控制事务之间的交互,即一个事务所做的更改在何时对其它事务可见。不同的隔离级别可以在并发性和一致性之间提供不同程度的平衡。SQL 标准定义了四种隔离级别,每种级别都可以减少一种或多种并发问题,但隔离级别越高,性能可能会越低,因为事务之间的并发能力减弱。

1. 读未提交(Read Uncommitted)
  • 定义:最低的隔离级别,允许事务读取尚未提交的数据变更,可能会导致脏读、不可重复读和幻读。
  • 问题:脏读。
  • 案例:事务A修改了一条数据但尚未提交,事务B在此时读取了这条未提交的数据。如果A回滚,B读到的数据就是错误的。
2. 读已提交(Read Committed)
  • 定义:允许事务读取并且仅读取已经提交的数据变更,可以避免脏读,但不可重复读和幻读仍可能发生。
  • 问题:不可重复读。
  • 案例:事务A读取了一条数据,事务B更新了这条数据并提交,当事务A再次读取同一数据时,数据已经变更。
3. 可重复读(Repeatable Read)
  • 定义:确保如果一个事务读取了一条记录,则在这个事务剩余的时间里,无论其他事务如何更新,都不会影响到这条记录的读取结果。可以避免脏读和不可重复读,但幻读仍可能发生。
  • 问题:幻读。
  • 案例:事务A读取了几行数据,事务B插入了一行新数据并提交,当事务A再次查询同一范围的数据时,会看到之前未出现的新行。
4. 串行化(Serializable)
  • 定义:最高的隔离级别,通过强制事务串行执行,避免脏读、不可重复读和幻读,但并发性能最差。
  • 问题:性能问题。
  • 案例:事务A和事务B需要操作同一数据集,B必须等待A完成并提交后,才能开始执行,从而保证了数据的一致性,但大大降低了并发性能。

并发问题解释:

  • 脏读(Dirty Reads):事务读取了另一个事务未提交的数据。
  • 不可重复读(Non-Repeatable Reads):事务在同一查询中多次读取同一数据集,结果却不同,因为其他事务在两次读取之间更新了数据。
  • 幻读(Phantom Reads):事务在重新执行针对某个范围的查询时,发现其他事务插入了满足查询条件的新数据。

在选择隔离级别时,需要在数据一致性和系统性能之间做出权衡。高隔离级别能更好地保证数据的一致性,但可能会降低系统的并发性能;低隔离级别虽然并发性能较好,但在数据一致性上可能存在缺陷。

MVCC:

MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种数据库事务并发控制的方法,主要用于解决读-写冲突,实现高并发访问数据库而不会出现数据不一致的情况。MVCC通过在数据库中保存数据的不同版本来实现并发控制,每个事务在执行时看到的数据版本都是一致的,但不同事务之间可以并发执行而不会相互影响。

MVCC实现原理:
1. 数据版本控制:

MVCC的核心思想是为每个数据项维护多个版本,并且每个事务只能看到适合自己版本的数据。数据库中的每个数据项都会有一个版本号或者时间戳与之关联。

  • 版本号:可以是整数或者时间戳,用于标识数据版本的顺序。
  • 时间戳:记录数据版本的生成时间,通常精确到毫秒或更高精度。
2. 版本链:

数据库中的数据通常以行(Row)为单位存储,每一行数据可能会有多个版本,这些版本按照时间顺序形成一个版本链。版本链可以用一个双向链表或者类似的数据结构来实现。

  • 每个数据行的版本链:包含了该数据行的所有版本,按照时间顺序排列。
  • 链表节点:存储了数据的具体内容以及指向下一个版本的指针。
3. 读操作实现:

当一个事务要执行读操作时,它会根据自己的事务ID或者时间戳确定要读取的数据版本,然后遍历该数据行的版本链,找到最接近但不超过事务版本的数据版本。

  • 快照读(Snapshot Read):事务读取数据时不会阻塞其他事务对同一数据的写操作,而是读取数据版本链中对应版本的数据。
  • 读取过程:事务通过版本链中的版本号或者时间戳来定位数据,确保读取到的数据是在该事务开始之前已经提交的。
4. 写操作实现:

当一个事务要执行写操作时,它会为数据生成一个新版本,并将新版本插入到数据行的版本链中。通常会使用写时复制(Copy-On-Write)或者类似的机制来实现写操作。

  • 生成新版本:事务会生成一个新的版本号或者时间戳,并将新版本写入到数据库中。
  • 写时复制:旧版本的数据不会立即被覆盖,而是在新版本生成后才被修改,这样可以保留旧版本的数据用于事务的隔离和回滚。
5. 提交操作实现:

当一个事务提交时,它会释放对数据库的锁,并清理与该事务相关的数据版本。这通常包括将该事务生成的新版本标记为已提交,并删除回滚段中与该事务相关的数据。

  • 释放锁:事务提交后,其他事务可以访问该数据,并且可以读取该事务生成的新版本。
  • 清理数据:删除回滚段中与该事务相关的数据,确保数据库的存储空间得到有效利用。
6. 事务隔离级别:

MVCC可以实现不同的事务隔离级别,包括读未提交、读已提交、可重复读和串行化。不同的隔离级别决定了事务对数据的读取和写入行为,从而影响了并发控制的实现方式。

  • 隔离级别:用于控制事务之间的相互影响程度,包括读取到的数据版本以及事务的可见性等方面。
总结:

MVCC通过多版本控制和版本链来实现数据库的并发控制,保证了事务之间的隔离性,从而确保了数据的一致性和完整性。MVCC是许多现代数据库系统的核心技术之一,如MySQL、PostgreSQL等都采用了MVCC来实现事务的并发控制。

MVCC实现流程:

当一个事务开始时,数据库系统会为其分配一个唯一的事务ID或者时间戳,并根据该事务ID或时间戳来执行读取和写入操作。

1. 读操作流程:
  1. 事务开始:事务T开始时,获取一个唯一的事务ID或时间戳。
  2. 确定读取版本:根据事务T的隔离级别,确定要读取的数据版本:
    • 如果隔离级别是读未提交,则可以读取到其他未提交事务的数据。
    • 如果隔离级别是读已提交或更高级别,则只能读取已提交事务生成的数据版本。
  3. 读取数据:根据确定的数据版本,从数据库中读取数据。通常是通过版本链中的版本号或时间戳来定位数据。
  4. 提交或回滚:如果读取数据时发现该数据已被删除或不可见,则根据事务的隔离级别决定是提交还是回滚该事务。
2. 写操作流程:
  1. 事务开始:事务T开始时,获取一个唯一的事务ID或时间戳。
  2. 生成新版本:为要写入的数据生成一个新版本,并将新版本插入到数据行的版本链中。通常采用写时复制或类似的机制来实现。
  3. 写入数据:将新版本的数据写入到数据库中。此时,其他事务仍然可以读取旧版本的数据,保持了数据的一致性。
  4. 提交或回滚:事务T完成所有写操作后,根据事务的提交或回滚指令来决定是否将写入的数据版本提交或回滚。
    • 如果提交事务,则将新版本标记为已提交,其他事务可以读取该版本。
    • 如果回滚事务,则删除新版本,并保留旧版本的数据。
3. 并发控制流程:
  1. 读-写冲突检测:当一个事务T1要读取数据时,如果发现有其他事务T2正在对该数据进行写操作,则需要进行冲突检测。
    • 如果T2的写操作已提交,则T1可以读取T2提交的新版本。
    • 如果T2的写操作未提交,则根据事务隔离级别决定是否允许T1读取T2的未提交数据。
  2. 写-写冲突检测:当一个事务T1要对数据进行写操作时,如果发现有其他事务T2正在对同一数据进行写操作,则需要进行冲突检测。
    • 如果T2的写操作已提交,则T1需要等待T2完成后再进行写操作。
    • 如果T2的写操作未提交,则根据事务隔离级别决定是否允许T1覆盖T2的未提交数据。
  3. 事务隔离级别的控制:根据事务的隔离级别,决定事务对数据的读取和写入行为,从而控制事务之间的相互影响程度。
  4. 并发度控制:根据系统的并发度限制,控制同时执行的事务数量,避免系统过载和性能下降。
4. 事务提交流程:
  1. 提交指令:当一个事务T完成所有操作后,执行提交指令。
  2. 标记提交:将事务T生成的新版本标记为已提交状态,其他事务可以读取该版本。
  3. 释放锁:释放事务T持有的锁资源,其他事务可以对相应数据进行读写操作。
  4. 清理数据:删除回滚段中与事务T相关的数据版本,释放存储空间。
  5. 提交完成:事务T提交完成,其他事务可以读取其写入的数据版本。

MVCC通过以上流程实现了数据库的并发控制,保证了事务之间的隔离性和数据的一致性。

MVCC案例说明:

假设有一个简单的数据库表,记录了用户的姓名和年龄,初始数据如下:

IDNameAge
1Alice25
2Bob30

现在有两个事务,T1 和 T2,分别对数据库进行操作:

  • 事务 T1
    1. T1 开始,读取 ID 为 1 的用户信息,姓名为 Alice,年龄为 25。
    2. T1 更新 ID 为 1 的用户信息,将年龄增加 1,变为 26。
    3. T1 提交事务。
  • 事务 T2
    1. T2 开始,读取 ID 为 1 的用户信息,姓名为 Alice,年龄为 25。此时由于T1未提交,T2读取到的是旧版本的数据。
    2. T2 提交事务。

通过MVCC,事务T2读取到了ID为1的用户信息时,虽然T1已经对该数据进行了更新,但T2读取到的是旧版本的数据,这样就避免了T2读取到脏数据的情况。

总的来说,MVCC通过版本控制实现了数据库的高并发访问,保证了事务之间的隔离性,从而确保了数据的一致性。

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

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

相关文章

AcWing 1388. 游戏(每日一题)

原题链接:1388. 游戏 - AcWing题库 玩家一和玩家二共同玩一个小游戏。 给定一个包含 N 个正整数的序列。 由玩家一开始,双方交替行动。 每次行动可以在数列的两端之中任选一个数字将其取走,并给自己增加相应数字的分数。(双方…

TCP三次握手,四次挥手

TCP为什么四次挥手?而不是三次? 正常流程:服务接收到 客户端的 FIN请求后,会发送一个ACK响应,等待系统资源释放后,再发送FIN 请求给客户端,客户端再发送一个ACK响应。 若为三次:就是…

unsigned和int相加减的错误

先看代码 #include<cstring> #include<vector> using namespace std; int main() {string s "12345678";int n s.length();cout << "n-10" << n - 10 << endl;cout << "s.length() - 10" << s.len…

第九届蓝桥杯大赛个人赛省赛(软件类)真题C 语言 A 组-航班时间

#include<iostream> using namespace std;int getTime(){int h1, h2, m1, m2, s1, s2, d 0;//d一定初始化为0&#xff0c;以正确处理不跨天的情况 scanf("%d:%d:%d %d:%d:%d (%d)", &h1, &m1, &s1, &h2, &m2, &s2, &d);return d …

基于Arduino nano配置银燕电调

1 目的 配置电调&#xff0c;设置电机转动方向&#xff0c;使得CW电机朝顺时针方向转动&#xff0c;CCW电机朝逆时针转动。 2 步骤 硬件 Arduino nano板子及USB线变阻器银燕电调EMAX Bullet 20A朗宇电机 2205 2300KV格氏电池3S杜邦线若干接线端子 软件 BLHeliSuite 注意…

数据库表设计18条黄金规则

前言 对于后端开发同学来说&#xff0c;访问数据库&#xff0c;是代码中必不可少的一个环节。 系统中收集到用户的核心数据&#xff0c;为了安全性&#xff0c;我们一般会存储到数据库&#xff0c;比如&#xff1a;mysql&#xff0c;oracle等。 后端开发的日常工作&#xff…

算法-数论-蓝桥杯

算法-数论 1、最大公约数 def gcd(a,b):if b 0:return areturn gcd(b, a%b) # a和b的最大公约数等于b与a mod b 的最大公约数def gcd(a,b):while b ! 0:cur aa bb cur%bpassreturn a欧几里得算法 a可以表示成a kb r&#xff08;a&#xff0c;b&#xff0c;k&#xff0c…

2024最新软件测试八股文,能不能拿心仪Offer就看你背得怎样了

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

2024.3.21力扣每日一题——频率跟踪器

2024.3.21 题目来源我的题解方法一 哈希表 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2671 我的题解 方法一 哈希表 两个哈希表&#xff0c;一个存储 [number&#xff0c;frequency]&#xff0c;一个存储[freuency,count]。当然这道题可以使用数组实现&#xff0c;…

Linux - mac 装 mutipass 获取 ubuntu

mutipass &#xff1a;https://multipass.run/docs/mac-tutorial mutipass list mutipass launch --name myname mutipass shell myname 获取 root权限&#xff1a; sudo su

xss相关知识点与绕过思路总结

前言 对xss的绕过进行了系统的学习与实践后&#xff0c;重新审视一下xss&#xff0c;对他的绕过进行一个总结。 &#xff08;当然我也是个小白&#xff0c;这些也是我当时瞎鸡儿乱搞绕过了几个xss自己做的小总结&#xff09; 可能有点丑陋&#xff0c;献丑了。 好博客推荐 …

生成式人工智能与 LangChain(预览)(上)

原文&#xff1a;Generative AI with LangChain 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 一、生成模型是什么&#xff1f; 人工智能&#xff08;AI&#xff09;取得了重大进展&#xff0c;影响着企业、社会和个人。在过去的十年左右&#xff0c;深度学习已经发…

【从零到一手撕脚手架 | 第四节】加速开发效率 使用plop生成开发模板 使用mock进行数据模拟

【从零到一手撕脚手架 | 第四节】加速开发效率 使用plop生成开发模板 使用mock进行数据模拟 Hello大家好我是⛄&#xff0c;之前我们已经配置了脚手架需要具备的基本功能&#xff1a;代码封装&#xff0c;团队协作规范等。但是可能我们有其他的需求&#xff0c;比如说我们想快速…

副业选择攻略:如何找到最适合自己的那一个?

大家好&#xff0c;我是木薯。今天有个新人伙伴来咨询客服&#xff1a;新手适不适合在水牛社上做副业&#xff1f;什么样的副业适合自己&#xff1f; 这种问题其实对我们来说已经见得太多太多了&#xff0c;归其原因是因为自己对副业没有一个清晰的自我认知&#xff0c;从而感觉…

基于LEAP模型的能源环境发展、碳排放建模预测及不确定性分析

在国家“3060”碳达峰碳中和的政策背景下&#xff0c;如何寻求经济-能源-环境的平衡有效发展是国家、省份、城市及园区等不同级别经济体的重要课题。根据国家政策、当地能源结构、能源技术发展水平以及相关碳排放指标制定合理有效的低碳能源发展规划需要以科学准确的能源环境发…

前视声呐目标识别定位(九)-声呐驱动

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …

Spring——框架介绍

每一个Java技术中都会存在一个“核心对象”&#xff0c;这个核心对象来完成主要任务为了得到核心对象&#xff0c;需要创建若干个辅助对象&#xff0c;从而导致开发步骤增加JDBC中 JDBC 核心对象——PreparedStatement 通过DriverManager得到数据库厂商提供的Driver对象DriverM…

京东云轻量云主机8核16G配置租用价格1198元1年、4688元三年

京东云轻量云主机8核16G服务器租用优惠价格1198元1年、4688元三年&#xff0c;配置为8C16G-270G SSD系统盘-5M带宽-500G月流量&#xff0c;华北-北京地域。京东云8核16G服务器活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云8核16G服务器优惠价格 京东云…

MySQL数据库基础--存储引擎

MySQL体系结构 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理&#xff0c;授权认证&#xff0c;及相关的安全方案&#xff0c;服务器也会为安全接入的每个客户端验证他所具有的操作权限。 服务层 第二层架构主要完成大多数的核心服务功…

【C++入门】缺省参数、函数重载与引用

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…