数据库事务

数据库事务

一、事务的基本特性 (ACID)

ACID不仅是四个特性,更是一个有机整体一致性(Consistency)是最终目的 ,原子性、隔离性、持久性是实现这一目的的三个核心手段

特性 核心含义 经典案例解析(A向B转账100元)
原子性 (Atomicity) 事务是最小工作单元,其包含的所有操作要么全部成功,要么全部失败回滚,不允许只执行一部分。 A账户-100和B账户+100这两个操作必须捆绑在一起。系统不会出现A的钱扣了,B的钱没到账的中间状态。
一致性 (Consistency) 事务的最终目的 。确保数据从一个正确的状态 转换到另一个正确的状态,满足所有预定义的业务规则和约束。 1. 数据状态一致: 转账后,总金额不变(A+B总额从600变为600)。 2. 业务约束一致: A账户余额不能为负(若A只有90元,则转账事务应失败);主键必须保持唯一等。
隔离性 (Isolation) 多个并发事务对同一数据进行操作时,事务之间是隔离的,不应相互干扰。这是防止并发操作导致数据不一致的关键。 当A向B转账的同时,如果C也向B转账,两个事务如果没有良好隔离,可能导致B的最终余额错误(如应是300,却得到200)。隔离级别定义了"干扰"的程度。
持久性 (Durability) 事务一旦提交,其对数据的修改就是永久性的,即使系统发生故障(如宕机),数据也不会丢失。 转账成功后,A=400,B=200的状态被持久化保存到存储介质。系统重启后,这个结果依然存在,不会回滚到转账前的状态。

核心逻辑链: 通过 原子性 确保操作完整,通过 隔离性 排除并发干扰,通过 持久性 固化结果,最终共同达成 一致性 这个根本目标。


二、事务的隔离级别

隔离级别解决的核心问题是:一个事务在操作数据时,如何看待其他并发事务对同一数据的修改?

隔离级别从低到高,数据安全性递增,但并发性能递减。

隔离级别 中文名 解决的问题 允许的并发问题 实现关键(以MySQL为例)
读未提交 (Read Uncommitted) 脏读 脏读、不可重复读、幻读 几乎不加锁,直接读最新数据(包括未提交的)。
读已提交 (Read Committed) 不可重复读 脏读 不可重复读、幻读 每次SELECT都生成新的 Read View ,只读取已提交的数据。Oracle默认级别
可重复读 (Repeatable Read) 幻读(部分) 脏读、不可重复读 幻读(在MySQL的InnoDB中,通过间隙锁已基本解决) 事务开始时生成一个Read View ,在整个事务期间复用,保证每次读到的数据快照一致。MySQL默认级别
串行化 (Serializable) - 脏读、不可重复读、幻读 无(但性能最低) 通过强制事务串行执行来实现最高隔离。

三、隔离级别引发的三大问题详解

通过"并发转账"或"重复查询"场景理解:

  1. 脏读 (Dirty Read)

    • 现象: 事务A读到了事务B尚未提交的修改。

    • 危害: 如果事务B最终回滚,事务A读到的就是根本不存在的"脏数据"。

    • 场景: 发生在读未提交级别。

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

    • 现象: 在同一个事务A内,两次读取同一条记录,得到的值不同。

    • 原因: 在两次读取之间,该记录被另一个已提交的事务B修改了。

    • 场景: 发生在读已提交级别,在可重复读级别中被解决。

  3. 幻读 (Phantom Read)

    • 现象: 在同一个事务A内,两次执行相同的条件查询 ,第二次查询结果集比第一次多出(或减少)了一些行(像出现了幻觉)。

    • 原因: 在两次查询之间,另一个已提交的事务B插入(或删除)了满足该查询条件的新数据。

    • 注意: 幻读关注的是结果集行数的变化 (新增/删除),而不可重复读关注的是同一行数据内容的变更

    • 场景:可重复读隔离级别理论上存在的问题。但MySQL的InnoDB引擎通过MVCC + 间隙锁的机制,在很大程度上避免了幻读


四、核心面试思路总结

  1. 不要死记硬背: 结合"转账"等业务场景理解ACID和隔离级别,理解其为什么存在 以及解决了什么问题

  2. 理解默认级别:

    • MySQL (InnoDB): 默认可重复读,并利用MVCC和锁机制有效防止了幻读。

    • Oracle / SQL Server: 默认读已提交

    • 能解释为什么不同数据库默认级别不同(权衡数据一致性与并发性能)。

  3. MVCC是理解关键: 读已提交可重复读级别的不同行为,本质上是生成Read View(一致性视图)的时机不同

    • 读已提交:每次SELECT都生成新Read View → 总能读到最新已提交数据 → 不可重复读

    • 可重复读:事务开始时生成一个Read View并复用 → 整个事务看到同一个数据快照 → 可重复读

  4. 理论与实践结合: 知道如果当前数据库的隔离级别不满足业务需求(如:在读已提交下需要避免不可重复读),应用层该如何做 (例如:使用SELECT ... FOR UPDATE加锁)。

  5. 区分概念: 清晰区分脏读、不可重复读、幻读 这三种现象,以及它们与丢失更新等问题的区别。

最终答案的层次: 从ACID的定义出发,阐述其内在联系,再过渡到为实现隔离性而设立的不同级别,用场景解释各级别的问题,并提及底层实现机制(如MVCC),展现出对事务全面、深入的理解。

相关推荐
老华带你飞4 小时前
二手商城|基于springboot 二手商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
@小码农4 小时前
6547网:2025年9月 Python等级考试(三级)真题及答案
服务器·数据库·python
千寻技术帮4 小时前
10393_基于SSM的杂志订阅网站管理系统
mysql·毕业设计·ssm·安装·文档·杂志订阅
IT教程资源C4 小时前
(N_122)基于springboot,vue网上订餐系统
mysql·vue·前后端分离·网上订餐系统·springboot网上订餐
老华带你飞4 小时前
酒店预约|基于springboot 酒店预约系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring
spencer_tseng4 小时前
mysql-8.0.44-winx64.msi VC_redist.2019.x64.exe
mysql
何妨呀~4 小时前
mysql 8服务器实验
android·mysql·adb
会飞的土拨鼠呀4 小时前
如何查询MySQL的CPU使用率突然变高
数据库·mysql
想用offer打牌4 小时前
一站式了解数据库三大范式(库表设计基础)
数据库·后端·面试