数据库事务的四大特性(ACID)

一、前言

在现代数据库系统中,事务(Transaction)是确保数据一致性和完整性的重要机制。事务的四大特性——原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),简称 ACID,是数据库事务处理的核心原则。

二、事务的四大特性详解

1. 原子性(Atomicity)

定义

原子性是指事务中的所有操作要么全部成功执行,要么全部失败回滚,不存在中间状态。事务是一个不可分割的最小工作单元。

作用
  • 防止部分操作成功而部分操作失败导致的数据不一致。
  • 例如,在银行转账场景中,扣款和加款必须同时成功或同时失败,否则会导致资金丢失或重复。
实现机制
  • 回滚日志(Undo Log):在事务执行前,数据库会记录操作的备份数据。如果事务失败,通过Undo Log将数据恢复到事务开始前的状态。
  • 原子操作:数据库引擎通过底层的原子操作(如行锁)确保事务的不可分割性。
实例分析

假设用户A向用户B转账100元:

  1. 从A账户扣除100元。
  2. 向B账户增加100元。
    如果步骤1成功但步骤2失败,事务会回滚,A和B的账户余额都会恢复到原始状态,避免资金异常。
技术实现
  • InnoDB存储引擎:通过Undo Log记录事务修改前的旧版本数据,支持回滚操作。
  • 日志系统:事务执行前,数据库将操作写入日志(如Redo Log),确保即使系统崩溃也能恢复。

2. 一致性(Consistency)

定义

一致性要求事务执行前后,数据库的完整性约束(如主键、外键、唯一性约束等)始终有效,数据必须从一个一致性状态转换到另一个一致性状态。

作用
  • 确保事务符合业务规则和逻辑。
  • 例如,银行账户的余额不能为负数,转账后总金额必须保持不变。
实现机制
  • 数据库约束:通过主键、外键、唯一索引等约束条件强制数据完整性。
  • 应用逻辑校验:在事务中编写业务规则校验(如库存不足时拒绝交易)。
  • 原子性+隔离性:事务的原子性和隔离性共同保障一致性。
实例分析

在电商系统中,用户下单时需扣除商品库存:

  1. 检查库存是否充足。
  2. 扣除库存并生成订单。
    如果库存不足,事务直接回滚,确保不会出现超卖现象。
技术实现
  • 约束校验:数据库在事务提交前进行约束检查(如外键约束、唯一性约束)。
  • 触发器(Triggers):通过触发器自动执行业务规则校验。

3. 隔离性(Isolation)

定义

隔离性要求多个并发事务之间相互隔离,彼此的操作互不干扰,避免并发执行导致的数据不一致问题(如脏读、不可重复读、幻读)。

作用
  • 解决并发事务的干扰问题。
  • 通过不同的隔离级别(如读已提交、可重复读、串行化)控制事务的可见性和并发程度。
实现机制
  • 锁机制:通过行锁、表锁等限制并发事务对数据的访问。
  • 多版本并发控制(MVCC):通过保存数据的多个版本,允许事务读取一致性快照,避免直接锁表。
  • 隔离级别
    • 读未提交(Read Uncommitted):最低级别,允许脏读。
    • 读已提交(Read Committed):避免脏读,但可能出现不可重复读。
    • 可重复读(Repeatable Read):避免脏读和不可重复读,但可能出现幻读(MySQL默认级别)。
    • 串行化(Serializable):最高级别,完全隔离,但并发性能最差。
实例分析

假设有两个并发事务同时修改同一商品的库存:

  1. 事务1:查询库存为100,准备下单。
  2. 事务2:查询库存为100,准备下单。
    如果隔离级别过低,可能导致两个事务都扣减库存,最终库存变为0,而实际应剩余50。通过锁机制或MVCC可以避免此类问题。
技术实现
  • InnoDB存储引擎:通过锁(行锁、间隙锁)和MVCC实现不同隔离级别的并发控制。
  • Read View:事务开启时生成一个Read View,记录当前活跃事务ID列表,通过版本链判断数据可见性。

4. 持久性(Durability)

定义

持久性要求事务一旦提交,对数据库的修改是永久性的,即使系统崩溃或断电,数据也不会丢失。

作用
  • 确保事务的提交结果持久化存储。
  • 例如,转账完成后,即使数据库宕机,账户余额的变化仍会被保留。
实现机制
  • 重做日志(Redo Log):事务提交时,数据库会将操作记录写入Redo Log,并持久化到磁盘。即使系统崩溃,恢复时可以通过Redo Log重放事务操作。
  • 磁盘持久化:数据最终会从内存刷新到磁盘,确保物理存储的可靠性。
实例分析

用户提交订单后,数据库会将订单信息写入Redo Log并刷新到磁盘。即使服务器突然断电,重启后仍能通过Redo Log恢复订单数据,避免数据丢失。

技术实现
  • 日志刷盘策略:通过innodb_flush_log_at_trx_commit参数控制Redo Log的刷盘频率。
  • 双写缓冲(Double Write Buffer):防止部分写失败导致数据损坏。

三、四大特性之间的关系

特性作用与其他特性的关系
原子性保证操作的完整性和回滚能力是一致性和持久性的基础
一致性事务的最终目标依赖原子性、隔离性和持久性共同实现
隔离性控制并发事务的干扰通过锁和MVCC保障一致性
持久性确保数据永久存储通过Redo Log和磁盘持久化实现

四、实际应用中的权衡

1. 性能与一致性

  • 高隔离级别(如串行化)能完全避免并发问题,但会降低并发性能。
  • 低隔离级别(如读未提交)性能高,但可能导致脏读、不可重复读等问题。

2. 分布式事务

  • 在微服务架构中,单数据库的ACID特性无法直接满足跨服务的事务需求,需通过分布式事务方案(如两阶段提交、TCC模式)实现最终一致性。

五、ACID特性在数据库中的实现

1. MySQL(InnoDB引擎)

  • 原子性:通过Undo Log记录旧版本数据,支持回滚。
  • 一致性:通过外键约束、唯一索引等保障数据完整性。
  • 隔离性:通过MVCC和锁机制(如行锁、间隙锁)实现不同隔离级别。
  • 持久性:通过Redo Log和双写缓冲确保数据持久化。

2. PostgreSQL

  • 原子性:通过Write-Ahead Logging(WAL)记录事务日志。
  • 一致性:通过约束检查和触发器保障。
  • 隔离性:基于MVCC实现,支持四种隔离级别。
  • 持久性:通过WAL日志和数据页刷盘实现。

六、ACID特性的挑战与优化

1. 并发控制的挑战

  • 锁冲突:高并发场景下,锁竞争可能导致性能下降。
  • 死锁:事务之间相互等待资源,需通过死锁检测和超时机制解决。

2. 性能优化策略

  • 选择合适的隔离级别:根据业务需求权衡一致性与性能。
  • 减少事务粒度:尽量缩短事务执行时间,减少锁持有时间。
  • 批量操作:通过批量插入/更新减少事务提交次数。

3. 分布式事务的解决方案

  • 两阶段提交(2PC):协调多个参与者提交或回滚。
  • TCC模式:通过Try-Confirm-Cancel三阶段实现最终一致性。
  • Saga模式:通过分解事务为多个本地事务,支持补偿机制。

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

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

相关文章

8 种快速易用的Python Matplotlib数据可视化方法

你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python 的 Matplotlib 库是你数据可视化的最佳伙伴!它简单易用、功能强大,能将枯燥的数字变成引人入胜的图表。无论是学生、数据分析师还是程序员&…

springboot 控制层调用业务逻辑层,注入报错,无法自动装配 解决办法

报错: 解决:愿意是业务逻辑层,即service层的具体实现类没有加注解Service导致的,加上解决了!!

如何提高独立服务器的安全性?

独立服务器相对于其它服务器来说,整体的硬件设备都是独立的同时还有着强大的服务器性能,其中CPU设备能够决定着服务器的运算能力,所以独立服务器的安全性受到企业格外的重视,严重的话会给企业造成巨大的资金损失。 那么&#xff0…

关于 Web 风险点原理与利用:6. 逻辑风险点

一、分类: 1.1 越权访问 **越权访问(Authorization Bypass)**是指:攻击者绕过了权限控制机制,访问或操作了非其权限范围内的资源或功能。 换句话说,系统该拦你没拦,你就越权成功了。 1.1.1 …

分布式缓存:ZSET → MGET 跨槽(cross‐slot)/ 并发 GET解决思路

文章目录 缓存全景图Pre问题描述解决思路一、管道(Pipelining)替代多线程二、使用 Hash Tag 保证数据同槽三、用 Hash 结构一次性批量取值四、把数据直接存进 ZSET(或用 RedisJSON) 小结 缓存全景图 Pre 分布式缓存:缓…

开发AR导航助手:ARKit+Unity+Mapbox全流程实战教程

引言 在增强现实技术飞速发展的今天,AR导航应用正逐步改变人们的出行方式。本文将手把手教你使用UnityARKitMapbox开发跨平台AR导航助手,实现从虚拟路径叠加到空间感知的完整技术闭环。通过本教程,你将掌握: AR空间映射与场景理…

助力 FPGA 国产化,ALINX 携多款方案亮相深圳、广州“紫光同创 FPGA 技术研讨会”

5 月中旬,一年一度的紫光同创技术研讨会系列活动正式拉开帷幕,相继在深圳、广州带来 FPGA 技术交流盛宴。 ALINX 作为紫光同创官方合作伙伴,长期助力推动 FPGA 国产化应用发展,此次携多款基于 Kosmo-2 系列产品开发的方案 demo 亮…

LeetCode 1040.移动石子直到连续II

在 X 轴上有一些不同位置的石子。给定一个整数数组 stones 表示石子的位置。 如果一个石子在最小或最大的位置,称其为 端点石子。每个回合,你可以将一颗 端点石子 拿起并移动到一个未占用的位置,使得该石子不再是一颗 端点石子。 值得注意的…

梯度优化提示词:精准引导AI分类

基于梯度优化的提示词工程方法,通过迭代调整提示词的嵌入向量,使其能够更有效地引导模型做出正确分类。 数据形式 训练数据 train_data 是一个列表,每个元素是一个字典,包含两个键: text: 需要分类的文本描述label: 对应的标签(“冲动"或"理性”)示例数据: …

JavaWeb:SpringBoot配置优先级详解

3种配置 打包插件 命令行 优先级 SpringBoot的配置优先级决定了不同配置源之间的覆盖关系,遵循高优先级配置覆盖低优先级的原则。以下是详细的优先级排序及配置方法说明: 一、配置优先级从高到低排序 1.命令行参数 优先级最高,通过keyvalu…

使用CentOS部署本地DeekSeek

一、查看服务器的操作系统版本 cat /etc/centos-release二、下载并安装ollama 1、ollama下载地址: Releases ollama/ollama GitHubGet up and running with Llama 3.3, DeepSeek-R1, Phi-4, Gemma 3, Mistral Small 3.1 and other large language models. - Re…

Matplotlib 后端与事件循环

前言:很多时候,matplot跑出来的是这种静态非交互的,如果想要可以交互,就得设定一个后端,例如 matplotlib.use(TkAgg)Matplotlib 后端 (Backend) Matplotlib 的设计理念是能够以多种方式输出图形,无论是显…

【JAVA】中文我该怎么排序?

📘 Java 中文排序教学文档(基于 Collator) 🧠 目录 概述Java 中字符串排序的默认行为为什么需要 Collator使用 Collator 进行中文排序升序 vs 降序排序自定义对象字段排序多字段排序示例总结对比表附录:完整代码示例 …

k8s-NetworkPolicy

在 Kubernetes 中,NetworkPolicy 是一种资源对象,用于定义 Pod 之间的网络通信策略。它允许你控制哪些 Pod 可以相互通信,以及如何通信。通过使用 NetworkPolicy,可以实现更细粒度的网络访问控制,增强集群的安全性。 1…

LAN(局域网)和WAN(广域网)

你的问题非常清晰!我来用一个直观的比喻实际拓扑图帮你彻底理解LAN(局域网)和WAN(广域网)如何协同工作,以及路由器在其中的位置。你可以把整个网络想象成一座城市: 1. 比喻:城市交通…

idea 插件开发自动发布到 nexus 私服中(脚本实例)

如下脚本内容为 idea 插件开发项目中的 build.gradle.kts 文件示例,其中自定了 updatePluginsXmlToNexus 和 uploadPluginToNexus 两个任务,一个用来自动修改 nexus 中的配置文件,一个用来自动将当前插件打包后的 zip 文件上传到 nexus 私服中…

SpringBoot-11-基于注解和XML方式的SpringBoot应用场景对比

文章目录 1 基于注解的方式1.1 @Mapper1.2 @select1.3 @insert1.4 @update1.5 @delete2 基于XML的方式2.1 namespace2.2 resultMap2.3 select2.4 insert2.5 update2.6 delete3 service和controller3.1 service3.2 controller4 注解和xml的选择如果SQL简单且项目规模较小,推荐使…

C++复习核心精华

一、内存管理与智能指针 内存管理是C区别于其他高级语言的关键特性,掌握好它就掌握了C的灵魂。 1. 原始指针与内存泄漏 先来看看传统C的内存管理方式: void oldWay() {int* p new int(42); // 分配内存// 如果这里发生异常或提前return&#xff0c…

期货反向跟单软件—提高盘手杠杆的方式及剖析

在期货反向跟单领域,期货跟单软件对盘手杠杆的调节,是整个策略运作的核心环节之一。其背后蕴含着科学的金融逻辑。​ 期货跟单软件提高盘手杠杆主要通过两种方式。第一种是降低期货保证金。在盘手资金总量固定的情况下,保证金降低&#xff0…

【计算机网络】基于UDP进行socket编程——实现服务端与客户端业务

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹: 【Linux笔记】——网络基础 🔖流水不争,争的是滔滔不息 一、UDPsocket编程UDPsocket编…