使用事务让 DB 更改可预测
Source: Dev.to
请提供您想要翻译的具体文本内容,我会将其翻译成简体中文并保留原有的格式、Markdown 语法以及技术术语。谢谢!
介绍
你好,我是 Maneshwar。我正在FreeDevTools online目前构建 一个集合所有开发工具、作弊代码和 TLDR 的地方——一个免费、开源的中心,开发者可以快速找到并使用工具,而无需在互联网上四处搜索。
在上一篇文章中,我们看到 索引 如何定义高效的访问路径,以及 DBMS 如何位于应用程序和存储之间,屏蔽应用程序免受文件、磁盘和故障的影响。
但还有一个更深层的问题是,仅靠索引和模式无法解决。
数据库不是静态的。它们代表 随时间演变的真实世界系统。
订单被下达,付款被处理,学生注册,余额变化。这些变化必须准确地反映在数据库中,即使在以下情况下:
- 多个用户同时操作
- 应用程序失败
- 系统崩溃
- 电源在操作中途中断
这就是 事务 概念不可避免的地方。
Source: …
为什么我们需要事务
用户在概念层面看到数据——关系、属性和约束。内部,DBMS 将数据存储在文件和块中,并维护索引和元数据。
应用程序修改数据库以映射现实世界的事件。这些修改通常涉及多个相关的数据项。
示例
- 从一个账户扣除金额
- 将金额添加到另一个账户
- 记录转账
这些更新必须相互一致。
更新期间的两大危险
-
临时不一致
- 当应用程序的逻辑执行到一半时,数据库可能处于中间状态。
- 如果其他应用程序看到此状态,它们可能会表现异常,即使它们本身编写得很完美。
-
更新过程中的故障
- 应用程序可能崩溃。
- 系统可能重启。
- 电源可能中断。
- 数据库可能留下部分更新、不一致的状态。
未被访问的数据库被假定为一致。
- 读取操作保持一致性。
- 写入操作暂时破坏一致性。
DBMS 必须确保这些临时不一致:
- 永不对其他人可见
- 在故障情况下永不成为永久状态
事务作为一致性单元
为了解决这个问题,来自应用程序的数据库操作会被 组合在一起。这组操作称为 事务。
事务是一个 逻辑工作单元:
- 由多个低层次的数据库操作组成
- 旨在将数据库从一个一致的状态转换到另一个一致的状态
当 独立执行 时,事务能够保持数据库的一致性。在事务活动期间,DBMS 假设:
“数据库 可能 此时不一致。”
因此,DBMS 会采取预防措施,直至事务完成。
事务到底是什么?
事务是对数据项的一系列操作。DBMS 的职责是让外部世界看到这系列操作表现为:
- 不可分割
- 瞬时
从其他事务的角度来看:
- 要么整个事务已经完成,要么
- 完全没有发生
不存在可见的中间状态。这个概念是 现代数据库系统的核心。几乎所有重要的数据库抽象——SQL、隔离级别、恢复日志——都是为支持事务而存在的。
关键点
- 由应用程序发起
- 由应用逻辑定义
- DBMS 假设它们是一致性的单元
- 代表 现实世界的事件(要么发生,要么不发生)
Source: …
提交、终止和完成
每个 DBMS 都提供事务接口,允许应用程序:
-
启动事务
-
执行数据库操作
-
以两种方式之一完成事务:
- 提交
- 终止
提交
当应用程序提交事务时,它告诉 DBMS:
“本事务所做的所有更改必须永久生效。”
一旦提交,事务的效果必须能够在以下情况下仍然保留:
- 崩溃
- 重启
- 电源故障
终止
当事务被终止时:
- 必须删除其所有效果
- 必须将数据库恢复到事务开始时的状态
终止可以发生:
- 显式,由应用程序发起
- 隐式,由 DBMS 强制(由于错误或约束违规)
在这两种情况下,一旦事务提交或终止,它就被视为 完成。应用程序只能 通过事务 与数据库交互。
Source: …
ACID 属性
在并发和故障的情况下确保正确性是困难的。为使其可管理,数据库管理系统(DBMS)保证一组统称为 ACID 的属性:
原子性 (Atomicity)
事务的所有操作要么:
- 全部发生,或
- 全部不发生
事务完成后不存在部分效果。失败或中止的事务在数据库中 不留下任何痕迹。
一致性 (Consistency)
如果事务从一致的数据库状态开始并在隔离环境中运行,它必须以一致的状态结束。
一致性涉及:
- 完整性约束
- 正确的业务逻辑
- 合法的状态转换
DBMS 强制执行约束,但 一致性的意义 来自应用程序和数据模型。
隔离性 (Isolation)
即使事务可能并发执行,最终结果必须 如同它们是串行执行一样。
从每个事务的视角来看:
- 它是单独运行的
- 它的操作看起来是瞬时完成的
隔离性防止事务看到:
- 暂时的不一致
- 其他事务的部分效果
持久性 (Durability)
一旦事务提交:
- 它的效果必须持久保存
- 即使系统随后立即崩溃
持久性将事务与我们之前学习的磁盘、日志和持久化机制联系起来。
数据库管理系统的保证与不保证的内容
数据库管理系统保证:
- 已提交事务的原子性、一致性、隔离性和持久性
- 使用日志和检查点从崩溃中恢复
- 并发控制,以防止并发事务之间的相互干扰
数据库管理系统不保证:
- 正确的应用逻辑(业务规则需由应用程序强制执行)
- 开发者正确编写事务(例如,避免死锁)
- 超出上述保证的性能特性(延迟、吞吐量)
ACID Guarantees
- 原子性
- 隔离性
- 持久性
- 完整性约束的强制执行
数据库管理系统 不:
- 理解应用语义
- 决定事务边界
- 在事务内部重新排序操作
应用定义
- 事务的作用
- 它包含的操作
- 何时提交或中止
DBMS遵循所发出的操作顺序。
Source: …
我们现在所处的位置
在此阶段,我们已经爬完了完整的抽象层级:
- 磁盘 解释持久性和故障
- 关系 定义结构
- 索引 定义访问路径
- 数据库管理系统 (DBMS) 协调存储和访问
- 事务 定义随时间变化的正确性
剩下的就是 DBMS 实际上如何在实践中强制实现 ACID。
这直接引出:
- 事务管理
- 并发控制
- 故障恢复
- 检查点
这些机制是理论与硬件系统工程相交汇的地方,也正是下一篇文章的起点。
👉 查看: FreeDevTools
欢迎任何反馈或贡献!
它已上线、开源,随时供任何人使用。
⭐ 在 GitHub 上给它加星: freedevtools
