数据库核心知识-数据库事务

「鸿蒙心迹」“2025・领航者闯关记“主题征文活动 10w+人浏览 508人参与

数据库事务

​ 数据库事务(Transaction)是数据库操作的最小逻辑工作单元,它将一组数据库操作(增删改查)封装成一个不可分割的整体 —— 要么这组操作全部执行成功并持久化,要么全部执行失败并回滚到初始状态。其核心价值是保证数据的一致性和可靠性,尤其在并发场景、金融交易(如转账)等关键业务中不可或缺。

一、事务的四大特性(ACID)

1. 原子性(Atomicity)

事务是一个不可分割的原子操作,就像 “原子不可再分” 一样,事务中的所有操作要么全部完成,要么全部不完成(失败后回滚),不存在中间状态。

举例:转账业务(A 账户扣 100 元,B 账户加 100 元)。如果 A 扣钱后,B 加钱失败,那么整个事务回滚,A 的钱会恢复,不会出现 “钱凭空消失” 的情况。

2. 一致性(Consistency)

事务执行前后,数据库的数据完整性约束(如主键唯一、外键关联、金额总和不变) 保持不变,数据从一个合法状态转换为另一个合法状态。

举例:转账前 A+B 的总金额是 2000 元,转账后 A+B 的总金额依然是 2000 元;如果转账导致某账户余额为负(违反完整性约束),事务会直接失败并回滚。

3. 隔离性(Isolation)

多个事务并发执行时,它们之间是相互隔离的,一个事务的执行不能被其他事务干扰。数据库通过隔离级别来控制隔离程度(隔离性越强,并发性能越差)。

举例:事务 A 正在读取某个账户的余额,事务 B 同时修改该余额,隔离性会保证事务 A 要么读到修改前的余额,要么读到修改后的余额,不会读到 “中间值”。

4. 持久性(Durability)

一个事务一旦提交(commit),其修改会被永久保存到数据库中,即使后续发生数据库崩溃、服务器宕机等故障,数据也不会丢失(底层依赖日志如 redo log 实现)。

举例:转账事务提交后,A 账户少 100、B 账户多 100 的结果会被永久保存,即使数据库重启,数据依然生效。

二、事务的并发问题(隔离性的反面)

当多个事务并发执行时,如果没有足够的隔离性,会出现以下问题(面试常考 “有哪些并发问题 + 如何解决”):

1. 脏读(Dirty Read)

一个事务读取到了另一个事务尚未提交的修改数据。

场景:事务 B 修改了账户余额为 500 元(未提交),事务 A 读取到这个 500 元,随后事务 B 回滚,事务 A 读到的就是 “脏数据”。

2. 不可重复读(Non-repeatable Read)

一个事务内多次读取同一数据,结果却不一致(因为其他事务提交了修改 / 删除操作)。

场景:事务 A 第一次读账户余额是 1000 元,事务 B 修改余额为 800 元并提交,事务 A 再次读该余额变成 800 元,前后结果不一致。

3. 幻读(Phantom Read)

一个事务内多次执行同一查询(如范围查询),结果集的行数不一致(因为其他事务提交了插入操作)。

场景:事务 A 查询 “余额> 500 的账户有 3 个”,事务 B 插入一个余额 600 的账户并提交,事务 A 再次查询时变成 4 个,像出现了 “幻觉”。

三、事务的隔离级别

​ 事务的隔离级别是为了解决多个事务并发执行时的干扰问题(脏读、不可重复读、幻读),SQL 标准定义了4 个核心隔离级别,不同数据库对隔离级别的支持和实现略有差异(比如 MySQL 的可重复读比标准更优)。下面从级别定义、解决的问题、数据库支持、性能特点等维度详细说明:

一、四大隔离级别

1. 读未提交(READ UNCOMMITTED)
  • 定义:最低的隔离级别,允许一个事务读取另一个事务尚未提交的修改数据。
  • 并发问题:会出现脏读、不可重复读、幻读(所有并发问题都存在)。
  • 典型场景:几乎不使用,仅在对性能要求极致且能容忍脏数据的特殊场景下考虑。
  • 性能:并发性能最高(因为几乎没有隔离限制)。
2. 读已提交(READ COMMITTED)
  • 定义:一个事务只能读取另一个事务已经提交的修改数据,无法读取未提交的数据。
  • 解决的问题:解决了脏读,但仍会出现不可重复读、幻读
  • 数据库支持:是 Oracle、SQL Server、PostgreSQL 等主流数据库的默认隔离级别
  • 性能:并发性能较高(仅次于读未提交)。
  • 举例:事务 A 第一次读取账户余额为 1000 元,事务 B 修改余额为 800 元并提交,事务 A 再次读取时会得到 800 元(前后读取结果不一致,即不可重复读)。
3. 可重复读(REPEATABLE READ)
  • 定义:保证同一事务内多次读取同一数据时,结果始终一致,不受其他事务提交的修改影响。
  • 解决的问题:解决了脏读、不可重复读MySQL 中额外解决了幻读(标准 SQL 的可重复读仍会出现幻读)。
  • 数据库支持:是MySQL InnoDB 存储引擎的默认隔离级别
  • 实现原理(MySQL):通过MVCC(多版本并发控制) 为事务提供一致性快照,结合next-key lock(临键锁) 防止幻读(锁定数据范围,避免其他事务插入数据)。
  • 性能:并发性能中等(平衡了隔离性和性能)。
  • 举例:事务 A 全程读取账户余额都是 1000 元,即使事务 B 修改并提交了余额,事务 A 直到结束都只会看到 1000 元。
4. 串行化(SERIALIZABLE)
  • 定义:最高的隔离级别,强制事务串行执行(相当于单线程处理事务),完全禁止并发操作。
  • 解决的问题:解决了所有并发问题(脏读、不可重复读、幻读全部消失)。
  • 实现方式:通过对整个数据范围加锁,事务执行时会阻塞其他事务的读写操作。
  • 性能:并发性能最低(因为串行执行,相当于放弃了并发)。
  • 典型场景:仅用于数据一致性要求极高的核心场景(如金融行业的资金清算、核心交易系统)。
隔离级别脏读不可重复读幻读并发性能
读未提交(READ UNCOMMITTED)最高
读已提交(READ COMMITTED)较高
可重复读(REPEATABLE READ)❌(MySQL)中等
串行化(SERIALIZABLE)最低

四、主流数据库默认隔离级别

数据库产品默认隔离级别关键补充说明
MySQL(InnoDB 引擎)可重复读(REPEATABLE READ)1. 并非标准的可重复读:通过MVCC+next-key lock解决了幻读(标准可重复读仍有幻读);2. MyISAM 引擎不支持事务,无隔离级别概念。
Oracle读已提交(READ COMMITTED)1. 支持串行化(SERIALIZABLE)和只读隔离级别;2. 可通过ALTER SESSION SET ISOLATION_LEVEL修改级别。
SQL Server读已提交(READ COMMITTED)1. 默认开启「读已提交快照隔离(RCSI)」,基于行版本控制减少锁竞争;2. 支持快照隔离(SNAPSHOT)、可序列化等级别。
PostgreSQL读已提交(READ COMMITTED)1. 支持可重复读、序列化,且其可重复读实现接近 MySQL 的机制;2. 可通过SET TRANSACTION ISOLATION LEVEL临时修改。
SQLite串行化(SERIALIZABLE)轻量级数据库,默认最高隔离级别,因并发场景少,性能影响可忽略。
MongoDB(4.0 + 支持事务)读已提交(READ COMMITTED)分布式文档数据库,事务仅支持副本集,默认读已提交。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值