【MySQL篇05】:事务的 ACID 性(数据库原理篇)

文章目录

  • 一、事务的ACID特性
  • 二、数据库原理例题与 ACID 特性判断
  • 三、拓展(undolog 与 redolog)

一、事务的ACID特性

综述:

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
  1. 原子性(Atomicity):

    • 通俗类比: 就像你去ATM取钱。整个取钱操作(输入密码、选择金额、出钞、打印凭条)是一个原子操作。如果中间任何一步失败了(比如机器故障没出钞),那么整个操作就会被撤销,你的账户余额不会改变,就像你没取过钱一样。如果全部成功,你的账户余额才会减少,你拿到钱。
    • 核心思想: 事务中的所有操作要么作为一个整体被执行成功,要么作为一个整体被回滚(撤销)。没有中间状态。
    • 实现方式: 通常通过日志(如Undo Log)来实现。如果事务执行过程中发生错误,系统会根据日志回滚到事务开始前的状态。
  2. 一致性(Consistency):

    • 通俗类比: 想象一个银行账户的总金额。在任何一个事务执行前后,所有账户的总金额应该保持不变(假设没有外部资金流入流出)。如果你从账户A转账100元到账户B,事务开始前,A+B的总金额是X。事务结束后,A减少100,B增加100,A+B的总金额仍然是X。这就是一致性。
    • 核心思想: 事务必须使数据库从一个一致性状态转换到另一个一致性状态。一致性状态是指数据库满足所有的预定义规则和约束(例如,主键唯一、外键引用有效、余额不能为负等)。
    • 实现方式: 依赖于原子性、隔离性、持久性,以及数据库本身的约束(如外键约束、唯一性约束、Check约束等)。程序员编写的业务逻辑也需要保证一致性。
  3. 隔离性(Isolation):

    • 通俗类比: 想象你在图书馆看书,旁边有人也在看书。隔离性就像是你们之间有隔板,互不影响。你在翻页、做笔记,旁边的人也在做自己的事情,你们不会看到对方操作的中间状态,也不会互相干扰。
    • 核心思想: 并发执行的事务之间互不干扰,每个事务都感觉自己是系统中唯一正在运行的事务。一个事务的中间结果对其他事务是不可见的。
    • 实现方式: 数据库提供了多种隔离级别(如读未提交、读已提交、可重复读、串行化),通过锁机制、多版本并发控制(MVCC)等技术来实现不同程度的隔离。
  4. 持久性(Durability):

    • 通俗类比: 你在电脑上写了一篇文档,点击了“保存”。即使电脑突然断电,当你重新开机时,你保存的文档依然存在。这就是持久性。
    • 核心思想: 一旦事务提交成功,它对数据库数据的改变就是永久性的,即使系统发生故障(如断电、崩溃)也不会丢失。
    • 实现方式: 通常通过将事务的修改写入到日志文件(如Redo Log)中来实现。即使数据还没有完全写入磁盘,只要相关的日志已经写入磁盘,系统恢复时就可以通过日志来重做(Redo)这些操作,恢复到事务提交后的状态。

二、数据库原理例题与 ACID 特性判断

下面我们通过一些例子来帮助你判断和理解这些特性。请判断每个例子主要体现了事务的哪种 ACID 特性。

例题 1:

你在一个电商网站上下单购买商品。这个操作包括:

  1. 从库存表中减少商品数量。
  2. 在订单表中插入一条新的订单记录。
  3. 从用户余额中扣除支付金额。

如果在执行过程中,扣除用户余额时发生了网络错误导致失败,整个下单操作被取消,库存数量和订单记录都没有发生改变。

请问:这个例子主要体现了事务的哪种特性?为什么?

答案与解析:

这个例子主要体现了事务的 原子性(Atomicity)

原因:整个下单过程被视为一个不可分割的单元。当其中一个步骤(扣除用户余额)失败时,整个事务被回滚,之前已经执行的步骤(减少库存、插入订单)也被撤销,系统回到了事务开始前的状态。这符合原子性“要么全部成功,要么全部失败”的定义。

例题 2:

一个银行系统中有规定:所有账户的总金额必须大于等于零。
现在有两个账户 A 和 B,A 有 1000元,B 有 500元。
一个事务从 A 账户转账 200元到 B 账户。
事务执行完成后,A 账户变为 800元,B 账户变为 700元。
此时,所有账户的总金额(800 + 700 = 1500)仍然大于等于零,符合银行系统的规定。

请问:这个例子主要体现了事务的哪种特性?为什么?

这个例子主要体现了事务的 一致性(Consistency)

原因:事务执行前后,数据库从一个一致性状态(所有账户总金额 >= 0)转换到了另一个一致性状态(所有账户总金额 >= 0)。尽管账户A和B的金额发生了变化,但它们的变化是相互抵消的,维护了数据库的业务规则和约束。

例题 3:

两个用户同时尝试购买同一件限量商品。
用户 A 的事务开始执行,查询到商品库存为 1。
用户 B 的事务几乎同时开始执行,也查询到商品库存为 1。
用户 A 的事务执行扣减库存操作,库存变为 0,然后提交。
用户 B 的事务也执行扣减库存操作,如果隔离性不好,它可能会在用户 A 提交前就看到库存为 1,然后也尝试扣减,导致库存变为 -1(超卖)。
但由于数据库的隔离机制,用户 B 在尝试扣减库存时,会发现库存已经被用户 A 修改为 0,从而导致用户 B 的扣减库存操作失败(或者被阻塞等待)。最终只有一个用户购买成功,库存变为 0。

请问:这个例子主要体现了事务的哪种特性?为什么?

这个例子主要体现了事务的 隔离性(Isolation)

原因:在并发环境下,多个事务同时访问和修改相同的数据。隔离性确保了每个事务的执行不受其他并发事务的干扰。在这个例子中,良好的隔离性防止了“超卖”问题的发生,保证了用户 B 在用户 A 提交后能够看到最新的库存状态,避免了基于过期数据进行操作。

例题 4:

你成功地完成了一笔订单支付,事务提交成功。
即使紧接着数据库服务器发生了突然的断电,当你重新启动数据库后,查询订单列表,仍然能够找到刚才支付成功的订单记录,并且你的账户余额也确实被扣除了。

请问:这个例子主要体现了事务的哪种特性?为什么?

这个例子主要体现了事务的 持久性(Durability)

原因:一旦事务提交成功,其对数据库的修改就被认为是永久的,即使系统发生故障,这些修改也不会丢失。数据库通过将提交的事务信息写入日志等方式来保证数据不会因为意外情况而丢失。


三、拓展(undolog 与 redolog)

Q1: 详细解释一下,数据库是如何实现 原子性 的吗?特别是当事务执行到一半发生崩溃时,数据库如何确保之前已经执行的操作被撤销?

A: 原子性是通过日志来实现的。数据库会记录事务的每一步操作。如果事务失败了,就可以根据日志把已经执行的操作撤销掉,回到事务开始前的状态。

Q2: “日志”具体是指哪种日志?撤销操作的原理是什么?

A: 数据库主要依赖 Undo Log 来实现原子性。Undo Log 记录了数据修改前的值。如果事务需要回滚,系统会读取 Undo Log,根据日志中记录的旧值将数据恢复到修改前的状态。

Q3: 那么,Undo Log 是在事务提交后才清除吗?如果在事务提交前数据库崩溃了,Undo Log 起什么作用?

A: Undo Log 不是在事务提交后立即清除,而是会保留一段时间,直到相关的事务彻底完成并且不再需要回滚。如果在事务提交前数据库崩溃了,当数据库重启进行恢复时,会检查未完成的事务,并利用 Undo Log 将这些未完成事务已经进行的修改回滚,确保这些事务是“不存在”的,这正是原子性的体现。

Q4: 你提到了 Undo Log 用于回滚。那么,持久性 是如何保证的呢?它依赖哪种日志?如果事务提交后,数据还没完全写入磁盘,但日志已经写入了,然后数据库崩溃了,数据还能恢复吗?

A: 持久性主要依赖 Redo Log。Redo Log 记录了数据修改后的值。当事务提交时,数据库会确保 Redo Log 相关的记录已经写入磁盘。即使数据页本身还没来得及写入磁盘,只要 Redo Log 已经持久化了,系统恢复时就可以通过读取 Redo Log 来重做(Redo)这些操作,将数据恢复到事务提交后的状态。

Q5: 所以,Redo LogUndo Log 在保证ACID特性中扮演了不同的角色。你能总结一下它们各自的主要作用吗?

A: 好的。简单来说,Undo Log 主要用于保证 原子性,它记录了数据修改前的状态,用于回滚事务。Redo Log 主要用于保证 持久性,它记录了数据修改后的状态,用于在系统崩溃恢复时重做已提交的事务。它们是数据库实现事务ACID特性的重要底层机制。

Q6: 你提到了 隔离性 有不同的级别,比如读未提交、读已提交、可重复读、串行化。你能简单解释一下“读未提交”隔离级别可能带来的问题吗?

A: 读未提交(Read Uncommitted)是隔离级别最低的。它允许一个事务读取另一个未提交事务的修改。这可能导致 脏读(Dirty Read) 问题。例如,事务A修改了一行数据但还没有提交,事务B读取了这行被修改但未提交的数据。如果事务A随后回滚了这次修改,那么事务B读取到的数据就是无效的、不存在的数据,这就是脏读。

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

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

相关文章

crawl4ai 框架的入门讲解和实战指南——基于Python的智能爬虫框架,集成AI(如NLP/OCR)实现自动化数据采集与处理

一、crawl4ai 框架简介 1. 框架定位 核心功能:基于Python的智能爬虫框架,集成AI(如NLP/OCR)实现自动化数据采集与处理 关键特性: 零配置快速启动(自动识别网页结构) 内置反反爬机制&#xff…

受够垃圾翻译!CodeBuddy 8 分钟造神器,划词秒翻 + 自动适配所有网页

本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 前言 作为一个天天泡在 GitHub 上扒项目的人,翻译问题简直是我 “挖宝” 路上的头号绊脚石!想研究国外大神的优质开源项目,不是被机翻软…

零基础设计模式——总结与进阶 - 2. 反模式

第五部分:总结与进阶 - 2. 反模式 (Anti-Patterns) 在软件开发中,我们追求良好的设计模式以构建健壮、可维护的系统。然而,同样存在一些常见的、导致不良后果的解决方案,这些被称为“反模式”。理解反模式,可以帮助我…

音视频流媒体高级开发-学习路线

原文作者:Linux 原文链接:音视频流媒体高级开发-学习路线 如果你想往音视频方向发展,那么本文一定要认真阅读~ 大家都知道音视频开发薪资高、门槛高、发展空间大,心里蠢蠢欲动,却不知道怎么入门,怎么进阶…

LINUX 通过rsync同步 免密备份

1,增加免密码用户密码 useradd backup echo "5566777" | passwd --stdin backup echo "backup ALL(ALL) ALL" >> /etc/sudoers # 源服务器操作 ssh client_usersource_server ssh-keygen -t rsa # 一路回车 ssh-copy-id serv…

在使用 HTML5 的 <video> 标签嵌入视频时,有时会遇到无法播放 MP4 文件的问题

原因分析: 只能播放声音,却无法播放视频。这通常是由于视频编码格式不兼容导致的。虽然 MP4 是一种常见的视频格式,但它包含多种编码方式,并非所有编码方式都受 HTML5 支持。 解决方案: 确认视频编码格式: …

【bugfix】记一次Spring Boot 配置层级错误导致数据库连接失败

前言:为什么你的数据库配置读不到? 在 Spring Boot 项目中,配置文件的层级(prefix) 是决定属性能否被正确解析的核心因素。一个看似微小的缩进错误,可能导致整个应用的数据库连接失败、服务启动异常&#…

wpf 队列(Queue)在视觉树迭代查找中的作用分析

文章目录 队列(Queue)在视觉树迭代查找中的作用分析示例代码一、队列的核心作用1. 替代递归的迭代机制2. 实现广度优先搜索(BFS) 二、队列的工作流程1. 初始化阶段2. 处理循环 三、队列操作的详细步骤查找过程分解: 四、为什么使用队列而不是其他数据结构1. 与栈(St…

快手数据开发面试SQL题:取窗口内排名第一和排名倒数第一的作为两个字段输出

目录 问题描述 样例数据表 sales 解决方案 第三步:使用条件聚合将多行合并为单行输出" 步骤1:计算排名的中间结果 中间结果输出: 步骤2:最终查询(处理并列情况) 最终输出结果: 关键点解释: RANK() OVER (PARTITION BY group_id ORDER BY amount DESC):…

第十六届蓝桥杯国赛(2025)C/C++B组 蓝桥星数字 独家解析

这题我中午是12点以后开始做的,只剩下1个小时了,12点50的时候完成了框架,但是细节总是实现不对,现在晚上来复盘的时候才把这题A出来了。 但是,就像高考的导数你整个思路都会,你死在了求导上。。。&#xf…

Google 的 Protocol Buffers 介绍

Protocol Buffers(简称 Protobuf)是由 Google 开发的一种高效、灵活、跨语言的数据序列化协议,广泛用于网络通信、分布式系统、持久化存储等场景。 一、什么是 Protocol Buffers? Protocol Buffers 是一种结构化的数据交换格式,类似于 XML 和 JSON,但更小、更快、更简单…

犀思云Fusion WAN与阿里云NIS深度融合,实现端到端智能可观测

随着“AI数智化”浪潮逐步深入行业,企业网络的复杂与故障感知日渐凸显。如何实现网络的高效运维、智能诊断与全域可视化管理,已成为企业上云的核心挑战。 近日,犀思云与阿里云达成深度产品级合作,将阿里云网络智能服务&#xff0…

基于gec6818的环境监测系统设计

一、设计要求 将环境中温湿度数值、环境的光照强度和烟雾的信息获取到开发板,显示在图形界面上。当温度值高于阈值时,温度指示灯变红、蜂鸣器告警并且启动直流电机正转降温;当湿度值高于阈值时,湿度指示灯变红、蜂鸣器告警并且继电器吸合接通…

c++中std::transform详解和应用代码示例

std::transform 是 C 标准库中非常常用的算法之一&#xff0c;属于 <algorithm> 头文件。它的作用是将一个&#xff08;或两个&#xff09;序列中的元素通过某个函数进行变换&#xff0c;并将结果输出到另一个序列中。 一、std::transform 作用总结 std::transform 支持…

Yolov5 使用

1.开发背景 在已有的 Conda 环境下实现目标检测标定。 2.开发需求 实现演示例子的图片标定。 3.开发环境 Ubuntu20.04 Conda Yolov5 4.实现步骤 4.1 安装环境 # 创建环境 python 版本建议 3.9 以上 conda create -n yolov5 python3.9# 进入环境 conda activate yolov5# …

资深Java工程师的面试题目(四)性能优化

以下是针对Java性能优化的面试题&#xff0c;涵盖前后端技术栈的常见优化方式&#xff0c;适合评估候选人对性能调优的理解和实际应用能力&#xff1a; 1. JVM性能调优 题目: 请说明JVM垃圾回收&#xff08;GC&#xff09;的常见类型及其适用场景&#xff0c;并描述如何通过J…

火山引擎TTS使用体验

文章目录 前言1. 简介1.1 能力体验1.2 功能特性1.3 音色列表1.4 收费情况 2. 开启服务2.1 创建应用2.3 使用服务介绍 3.Websocket接入演示3.1 编写demo3.2 代码解释3.4运行demo 4. 参考链接 前言 语音合成TTS&#xff08;text to Speech&#xff09;是我觉得后续开发产品所不可…

Django中使用流式响应,自己也能实现ChatGPT的效果

最近在研究ChatGPT的时候&#xff0c;想通过openai提供的接口使国内用户也可以无限制访问&#xff0c;于是打算基于django开发一款应用。页面的渲染也得想ChatGPT一样采用流式响应&#xff0c;django中StreamingHttpResponse是支持流式响应的一种方式。 django 代码 class Ch…

Python Redis 简介

Redis 是一个高性能的内存键值数据库&#xff0c;支持多种数据结构&#xff08;字符串、列表、哈希、集合等&#xff09;&#xff0c;常用于缓存、消息队列和实时数据处理。Python 通过 redis-py 库与 Redis 交互。 核心功能 内存存储&#xff1a;数据存储在内存中&#xff0c…

mac安装whistle代理抓包工具(支持mock)

工具地址&#xff1a;https://wproxy.org/whistle/ 1、 安装nodejs环境 参考方法&#xff1a;https://github.com/nvm-sh/nvm 1&#xff09;安装 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash如图&#xff0c;安装成功 2&#xff09;…