【数据库】通俗易懂掌握事务的ACID特性与实现原理

在数据库的世界中,事务(Transaction)是一个非常重要的概念。无论是银行转账、订单支付,还是库存管理,事务都扮演着至关重要的角色。它确保了数据的一致性和完整性,避免了数据混乱和错误。本文将深入探讨事务的概念、ACID特性、实现原理以及实际应用场景,帮助你更好地理解为什么事务如此重要。


1. 什么是事务?

事务是数据库操作的一个逻辑单元,它包含一组操作,这些操作要么全部成功,要么全部失败。事务的核心目标是确保数据的一致性完整性

举个例子:
假设你在网上购物,点击“支付”按钮后,系统需要完成以下操作:

  1. 从你的账户扣款。
  2. 将款项转入商家账户。
  3. 更新订单状态为“已支付”。

如果这些操作中的任何一个失败(比如你的账户余额不足),整个支付过程应该被撤销,否则会导致数据不一致(比如钱扣了,但订单状态没更新)。事务就是为了解决这种问题而存在的。


2. 事务的ACID特性

事务的ACID特性是数据库事务的核心原则,它包括以下四个特性:

2.1 原子性(Atomicity)

原子性是指事务中的所有操作要么全部成功,要么全部失败。事务是一个不可分割的最小单位。

举例说明:
假设你给朋友转账100元,事务包含两个操作:

  1. 从你的账户扣除100元。
  2. 向朋友的账户增加100元。

如果第二步失败(比如朋友的账户不存在),那么第一步的扣款操作也会被撤销,确保你的钱不会凭空消失。

2.2 一致性(Consistency)

一致性是指事务执行前后,数据库的状态必须保持一致。这意味着事务必须遵循数据库的约束规则(如唯一性、外键约束等)。

举例说明:
假设有一个规则:账户余额不能为负数。如果你尝试从一个余额为50元的账户转账100元,事务会因为违反一致性规则而失败。

2.3 隔离性(Isolation)

隔离性是指多个事务并发执行时,一个事务的操作不会被其他事务干扰。每个事务都感觉不到其他事务的存在。

举例说明:
假设你和朋友同时向同一个账户转账。如果没有隔离性,可能会导致数据混乱(比如余额计算错误)。通过隔离性,数据库会确保每个事务按顺序执行,或者通过锁机制避免冲突。

2.4 持久性(Durability)

持久性是指事务一旦提交,它对数据库的修改就是永久性的,即使系统崩溃也不会丢失。

举例说明:
如果你成功支付了一笔订单,即使数据库服务器突然断电,支付记录也不会丢失。数据库会通过日志等方式确保数据的持久性。


3. 事务的使用场景

事务在现实生活中有广泛的应用场景。以下是一些常见的例子:

3.1 银行转账

银行转账是事务的经典应用场景。转账操作必须保证原子性,否则会导致资金损失或数据不一致。

代码示例:

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; -- 从用户1扣款
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2; -- 向用户2转账
COMMIT;

如果第二步失败,事务会回滚,撤销第一步的操作。

3.2 订单支付

在电商平台中,订单支付涉及多个操作,如扣款、更新库存、修改订单状态等。这些操作必须作为一个事务来执行。

代码示例:

BEGIN TRANSACTION;
UPDATE users SET balance = balance - 100 WHERE user_id = 1; -- 扣款
UPDATE products SET stock = stock - 1 WHERE product_id = 101; -- 减库存
UPDATE orders SET status = 'paid' WHERE order_id = 1001; -- 更新订单状态
COMMIT;

3.3 库存管理

在库存管理系统中,事务可以确保库存数量的准确性。例如,当多个用户同时购买同一商品时,事务可以避免超卖问题。

代码示例:

BEGIN TRANSACTION;
SELECT stock FROM products WHERE product_id = 101 FOR UPDATE; -- 锁定库存
IF stock > 0 THEN
    UPDATE products SET stock = stock - 1 WHERE product_id = 101; -- 减库存
    INSERT INTO orders (user_id, product_id) VALUES (1, 101); -- 创建订单
END IF;
COMMIT;

4. 事务的实现原理

事务的ACID特性是通过一系列底层机制实现的。下面我们深入探讨这些机制。

4.1 日志(Logging)

日志是事务实现的核心机制之一。数据库通过日志记录事务的所有操作,包括数据的修改和事务的状态(开始、提交、回滚)。日志的主要作用是支持故障恢复和确保持久性。

日志的类型:

  1. Undo Log(回滚日志):记录事务修改前的数据值,用于回滚操作。
  2. Redo Log(重做日志):记录事务修改后的数据值,用于恢复已提交的事务。
  3. Binary Log(二进制日志):记录所有修改数据的SQL语句,用于数据复制和恢复。

举例说明:
假设一个事务修改了某条记录的值:

  • Undo Log会记录修改前的值(旧值)。
  • Redo Log会记录修改后的值(新值)。

如果事务需要回滚,数据库会使用Undo Log将数据恢复到旧值。如果系统崩溃,数据库会使用Redo Log重新执行已提交的事务,确保数据的持久性。

4.2 锁(Locking)

锁是保证事务隔离性的关键机制。通过锁,数据库可以控制并发事务对数据的访问,避免数据冲突。

锁的类型:

  1. 共享锁(Shared Lock):允许多个事务同时读取数据,但不允许修改。
  2. 排他锁(Exclusive Lock):只允许一个事务读取或修改数据,其他事务无法访问。

举例说明:
假设事务A和事务B同时操作同一条记录:

  • 如果事务A获取了共享锁,事务B也可以获取共享锁来读取数据。
  • 如果事务A获取了排他锁,事务B必须等待事务A释放锁后才能访问数据。

4.3 多版本并发控制(MVCC)

MVCC是一种提高并发性能的技术,它通过为每个事务创建数据的不同版本来避免锁冲突。

MVCC的工作原理:

  1. 每个事务在开始时会被分配一个唯一的事务ID。
  2. 数据库会为每条记录维护多个版本,每个版本包含创建和删除的事务ID。
  3. 事务只能看到在其开始之前提交的数据版本。

举例说明:
假设事务A和事务B同时操作同一条记录:

  • 事务A修改了记录,创建了一个新版本。
  • 事务B读取记录时,只能看到事务A修改前的版本,从而避免了冲突。

4.4 检查点(Checkpoint)

检查点是数据库定期将内存中的数据写入磁盘的过程。它有助于减少故障恢复的时间。

检查点的作用:

  1. 将内存中的脏页(已修改但未写入磁盘的数据)写入磁盘。
  2. 更新日志文件,标记已持久化的数据。

举例说明:
假设数据库每隔5分钟执行一次检查点:

  • 在检查点之前提交的事务,其数据会被写入磁盘。
  • 如果系统崩溃,数据库只需要从最近的检查点开始恢复,而不是从头开始。

5. 事务的隔离级别

在实际应用中,多个事务可能会同时操作同一数据。为了平衡性能和数据一致性,数据库提供了不同的隔离级别:

  1. 读未提交(Read Uncommitted):事务可以读取其他事务未提交的数据。可能导致“脏读”。
  2. 读已提交(Read Committed):事务只能读取其他事务已提交的数据。避免了脏读,但可能导致“不可重复读”。
  3. 可重复读(Repeatable Read):事务在执行期间多次读取同一数据时,结果一致。避免了不可重复读,但可能导致“幻读”。
  4. 串行化(Serializable):事务完全隔离,避免了脏读、不可重复读和幻读,但性能最差。

举例说明:
假设有两个事务同时操作账户余额:

  • 事务A:查询余额,得到100元。
  • 事务B:更新余额为200元并提交。
  • 事务A:再次查询余额。

在不同的隔离级别下,事务A的第二次查询结果可能不同:

  • 读未提交:事务A可能读取到事务B未提交的数据(比如150元)。
  • 读已提交:事务A只能读取到事务B提交后的数据(200元)。
  • 可重复读:事务A的两次查询结果一致(100元)。
  • 串行化:事务A和事务B完全隔离,按顺序执行。

6. 总结

事务是数据库的核心功能之一,它通过ACID特性确保了数据的一致性和完整性。无论是银行转账、订单支付,还是库存管理,事务都发挥着不可替代的作用。通过理解事务的原理和应用场景,我们可以更好地设计可靠的系统,避免数据错误和混乱。

希望本文能帮助大家深入理解事务的概念和重要性。end~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python 初级函数详解】—— 参数沙漠与作用域丛林的求生指南

欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡 本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创&#x1…

MacBook Pro使用FFmpeg捕获摄像头与麦克风推流音视频

FFmpeg查看macos系统音视频设备列表 ffmpeg -f avfoundation -list_devices true -i "" 使用摄像头及麦克风同时推送音频及视频流: ffmpeg -f avfoundation -pixel_format yuyv422 -framerate 30 -i "0:1" -c:v libx264 -preset ultrafast -b:v 1000k -…

42 session反序列化漏洞

参考资料:3. php反序列化从入门到放弃(入门篇) - bmjoker - 博客园 session文件上传漏洞利用原理 当在php.ini中设置session.upload_progress.enabled On的时候,PHP将能够跟踪上传单个文件的上传进度。当上传正在进行时,以及在将与session…

leetcode第77题组合

原题出于leetcode第77题https://leetcode.cn/problems/combinations/ 1.树型结构 2.回溯三部曲 递归函数的参数和返回值 确定终止条件 单层递归逻辑 3.代码 二维数组result 一维数组path void backtracking(n,k,startindex){if(path.sizek){result.append(path);return ;}…

基于html的俄罗斯方块小游戏(附程序)

一、前言 俄罗斯方块(Tetris)是一款经典的益智游戏,由苏联程序员阿列克谢帕基特诺夫(Alexey Pajitnov)于1984年开发。这款游戏最初是为减少计算机的恐怖效果而设计的,后来通过盗版传播到全球,成…

openwebUI访问vllm加载deepseek微调过的本地大模型

文章目录 前言一、openwebui安装二、配置openwebui环境三、安装vllm四、启动vllm五、启动openwebui 前言 首先安装vllm,然后加载本地模型,会起一个端口好。 在安装openwebui,去访问这个端口号。下面具体步骤的演示。 一、openwebui安装 rootautodl-co…

机器学习:线性回归,梯度下降,多元线性回归

线性回归模型 (Linear Regression Model) 梯度下降算法 (Gradient Descent Algorithm) 的数学公式 多元线性回归(Multiple Linear Regression)

加入二极管的NE555 PWM 电路

只用电阻、电容构成的一般定时电路的占空比无法低于50%,如下图: 电容的充电路径上串联了R1 和R2,而放电路径上只有R2,所以放电的时间不可能比充电长。加入二极管就能解决这个问题,用二极管把充电和放电路径分离开&…

游戏引擎学习第131天

仓库:https://gitee.com/mrxiao_com/2d_game_3 运行游戏并识别我们的小问题 今天的工作重点是对游戏引擎进行架构优化,特别是针对渲染和多线程的部分。目前,我们的目标是让地面块在独立线程上进行渲染,以提高性能。在此过程中,我…

并发编程1

JAVA线程回顾 多线程 多个并行的线程来完成个自的任务,优点是程序响应速度更快,程序性能得到提升。 并行执行与并发执行 并发执行就是在单核CPU下,现成实际上是串行执行的,任务调度器将cpu的时间片分给不同的线程使用&#xff0…

AI: Cursor是否已奠定AI开发环境的龙头地位?

近年来,人工智能(AI)在软件开发领域的应用迅速升温,而Cursor作为一款AI驱动的代码编辑器,凭借其创新功能和市场表现,引发了广泛讨论。许多人认为,Cursor已经奠定了AI开发环境的龙头地位。然而&a…

贪心算法+题目

贪心算法 跳跃游戏跳跃游戏2 跳跃游戏 题目 拿到题目就暴力穷举,我用的是dfs,加上备忘录之后还是超出时间限制。就考虑一下贪心算法。你想 我在[0,n-2]位置遍历求出可以跳跃的最远距离,用farthest更新最大值,如果>终点就返回t…

02 2个交换机+vlan构造两个逻辑上的子网

前言 这是最近一个朋友的 ensp 相关的问题, 这里来大致了解一下 ensp, 计算机网络拓扑 相关基础知识 这里一系列文章, 主要是参照了这位博主的 ensp 专栏 这里 我只是做了一个记录, 自己实际操作了一遍, 增强了一些 自己的理解 当然 这里仅仅是一个 简单的示例, 实际场景…

【前端基础】Day 7 CSS高级技巧

目录 1. 精灵图 1.1 为什么需要精灵图 1.2 精灵图(sprites)的使用 2. 字体图标 2.1 字体图标的产生 2.2 字体图标的优点 2.3 字体图标的下载 2.4 字体图标的引入 2.5 字体图标的追加 3. CSS三角形 4. CSS用户界面样式 4.1 更改用户鼠标样式 …

React低代码项目:问卷编辑器 II

吐司问卷:问卷编辑器 II Date: February 26, 2025 Log **软件设计的可拓展性:**对修改封闭,对拓展开放 工具栏 删除组件 需求: 要点: 实现删除选中组件 思路:重新计算 selectedId,优先选择…

图像处理之图像边缘检测算法

目录 1 图像边缘检测算法简介 2 Sobel边缘检测 3 经典的Canny边缘检测算法 4 演示Demo 4.1 开发环境 4.2 功能介绍 4.3 下载地址 参考 1 图像边缘检测算法简介 图像边缘检测是计算机视觉和图像处理中的基本问题,主要目的是提取图像中明暗变化明显的边缘细节…

数据结构(初阶)(八)----排序

排序 概念 排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的⼤⼩,递增或递减的排列起来的 操作。 比较排序 插入排序 直接插入排序 直接插⼊排序是⼀种简单的插⼊排序法,其基本思想是:把待…

计算机毕业设计SpringBoot+Vue.js基于JAVA语言的在线考试与学习交流网页平台(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

聊一聊 IM 如何优化数据库

IM 系列 im doc 实时通讯文档仓库 聊一聊 IM 是什么? IM 即时通讯系统概览 聊一聊 IM 要如何设计? 聊一聊 IM 要如何设计功能模块? 聊一聊 IM 要如何进行架构设计? 聊一聊 IM 要如何进行技术选型? 聊一聊 IM 要…

人工智能AI在汽车设计领域的应用探索

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活…