事务详解及面试常考知识点整理
1. 什么是事务?
**事务(Transaction)**是将多条 SQL 语句打包执行的操作单元,具有"一气呵成"的特性。就好比你要完成"把大象放进冰箱"这件事,一共分三步:
- 打开冰箱门
- 把大象放进去
- 关上冰箱门
这三步操作必须作为一个整体完成,否则就不能称之为"把大象放进冰箱"。这就是一个事务的概念。
为什么需要事务?
现实中,很多操作必须是原子性的,比如银行转账。你妈妈给你打生活费:
- 从她的账户扣除 1000 元
- 给你的账户增加 1000 元
这两个步骤必须同时成功。如果在第一个步骤完成后,系统宕机了,而第二步未执行成功,你妈妈的钱扣掉了,但你却没有收到,这显然是不可以接受的。
因此,我们需要事务 来保证这类操作的可靠性和一致性。事务的作用就是:要么全部成功,要么全部失败。
💡 即使出现故障,事务也能通过"回滚(rollback)"机制恢复数据库状态,仿佛"什么都没发生过"。
2. 事务的基本操作
事务的基本流程如下:
sql
START TRANSACTION; -- 开始事务
-- 多条SQL操作
COMMIT; -- 提交事务
-- 或
ROLLBACK; -- 回滚事务(撤销之前的所有操作)
在 START TRANSACTION
与 COMMIT
之间的 SQL 操作,构成一个完整的事务。
实际开发中,还会配合业务逻辑编程语言(如 Java、Python)做错误处理或手动触发回滚。
3. 回滚(Rollback)是如何实现的?
事务的回滚是通过日志机制实现的。MySQL 会在执行下一条 SQL 前,把当前状态写入日志文件。如果后续操作失败,就从日志中恢复数据。
比如你写代码的时候,每改完一段就保存一次。如果发现写错了,可以"撤销(Ctrl+Z)"返回上一个保存点。数据库也是类似的原理。
✅ 即使断电或系统崩溃,只要日志在磁盘上,MySQL 也能在重启后进行恢复。
4. 事务的四大特性(ACID)------面试高频考点!
事务的四大特性简称为 ACID:
(1)原子性(Atomicity)
事务是一个不可分割的整体。就像打包的快递,要么整个快递成功送达,要么压根就没有发货。
(2)一致性(Consistency)
事务执行前后,数据库都必须处于一致状态。
示例:你妈妈给你转 1000 元,执行完事务后,妈妈账户少 1000,你账户多 1000。总额没变,这就是一致性。不能出现"转了 1000,你收到 8000"这种现象。
(3)持久性(Durability)
事务一旦提交,修改将永久保存,即使服务器宕机也不会丢失。
示例:你做完一个大项目,点了"保存"。电脑突然蓝屏,但重启后还能找到文件,这就是持久性带来的保护。
(4)隔离性(Isolation)
多个事务并发执行时,相互之间不应互相干扰。并发控制是事务系统的一大难点。
5. 并发执行下的事务问题及隔离级别
什么是并发执行?
比如你和室友一起做饭,只有一个炉灶,就得排队做(串行);但如果有两个灶,就能同时炒菜(并发)。数据库中的并发执行可以提升处理效率,但也容易引发问题。
下面是三大经典并发问题 ,每一个问题都有对应的隔离级别来解决。
问题一:脏读(Dirty Read)
定义:一个事务读取了另一个未提交事务修改的数据。
例子:
你正在写代码(事务 A),同学来抄作业(事务 B)。你突然发现写错了就撤回修改,而同学却抄走了你写错的版本。这就是"脏读"。
**解决方案:**给写操作加锁,只有等事务提交后,其他事务才能读取,避免读到未确认数据。
问题二:不可重复读(Non-repeatable Read)
**定义:**同一个事务在两次读取同一数据时,结果却不同,因为其他事务在中间修改了数据。
例子:
你同学在看你的作业(读取),你把作业改了并重新提交,他再看一次,内容已经不一样了,他就懵了。
**解决方案:**给读操作加锁,在整个事务执行期间,不允许其他事务修改已读取的数据。
问题三:幻读(Phantom Read)
**定义:**同一个事务中,多次读取符合条件的数据时,返回的行数发生变化。
例子:
你同学抄完代码 A 后再刷新页面,突然发现多了段代码 B(你新增的)。他以为这是你原来写的,也一起交了上去,这就是幻读。
**解决方案:**只有最高隔离级别"串行化(Serializable)"才能避免幻读,但效率最低。
6. MySQL 的四种隔离级别(按从低到高)
隔离级别 | 能否避免脏读 | 能否避免不可重复读 | 能否避免幻读 | 并发性能 |
---|---|---|---|---|
Read Uncommitted | ✗ | ✗ | ✗ | 高 |
Read Committed | ✓ | ✗ | ✗ | 较高 |
Repeatable Read | ✓ | ✓ | ✗(默认) | 中 |
Serializable | ✓ | ✓ | ✓ | 低 |
💡 MySQL 默认隔离级别是:Repeatable Read
7. 总结与建议
事务本质上是为了解决数据一致性与并发效率之间的矛盾。在设计数据库操作时:
- 若业务要求强一致性(如转账、库存),优先选择高隔离级别;
- 若业务对一致性要求不高(如点赞数统计),可使用低隔离级别以换取高性能。
如果你正在准备数据库或后端开发方向的面试,请务必掌握以下几点:
- 事务四大特性(ACID)
- 三大并发问题(脏读、不可重复读、幻读)
- 四种隔离级别及其对应能力
- MySQL 默认的隔离级别
如需更深入地学习事务的原理与实现,如Undo Log、Redo Log、MVCC机制等,请在评论区留言或关注后续更新!
如果你有任何数据库方面的困惑,欢迎留言或私信交流 😊