一、什么是事务
在数据库领域,事务(Transaction)是并发控制的基本单位。它是由用户定义的一系列操作组成的逻辑工作单元,这些操作要么全部成功执行,要么全部回滚,是一个不可分割的整体。
在实际开发中,事务通常显式开启于 BEGIN TRANSACTION,并以 COMMIT(提交)或 ROLLBACK(回滚)来结束。这种机制确保了数据操作的完整性。
二、事务的四大特征(ACID)
理解事务,离不开它的四个核心属性:
- 原子性(Atomicity):事务是数据库的逻辑工作单位,其中的操作具有'全有或全无'的特性,不会停留在中间状态。
- 一致性(Consistency):无论事务如何执行,最终结果必须使数据库从一个一致的状态转换到另一个一致的状态。这通常依赖于约束、触发器和外键等机制来保证。
- 隔离性(Isolation):多个事务并发执行时,彼此之间不应相互干扰。一个事务内部的操作及使用的数据对其他并发事务是隔离的。
- 持久性(Durability):一旦事务提交,它对数据的修改就是永久性的。即使后续发生系统故障,已提交的数据也不会丢失。
三、并发环境下的常见问题
当多个线程或进程同时操作数据库时,如果没有适当的隔离机制,数据准确性就会受到威胁。以下是三种典型的并发异常:
1. 脏读(Dirty Read)
指一个事务读取了另一个事务尚未提交的数据。如果那个未提交的事务随后回滚,当前事务读取到的就是无效数据。
2. 不可重复读(Non-repeatable Read)
指在一个事务内,多次查询同一行数据返回的结果不一致。这通常是因为在两次查询之间,另一个事务修改并提交了该行数据。
3. 幻读(Phantom Read)
指在一个事务的两次查询中,数据行数不一致。例如,事务 A 查询某范围数据后,事务 B 在此范围内插入了新数据并提交,导致事务 A 再次查询时发现多出了几行记录。
对比理解:脏读和不可重复读的区别在于是否读取了'已提交'的数据;而不可重复读针对的是单个数据项,幻读则关注一批数据整体(如行数)。
四、事务隔离级别
为了解决上述问题,SQL 标准定义了四种隔离级别,级别越高,数据越安全,但并发性能越低。
-
Read Uncommitted(读未提交) 允许读取其他事务未提交的数据。此级别无法解决任何并发问题,实际应用中极少使用。
-
Read Committed(读已提交) 只能读取其他事务已提交的数据。它解决了脏读问题,但无法避免不可重复读和幻读。Oracle 默认采用此级别。
-
Repeatable Read(可重复读) 保证同一事务内的多次读取结果一致。它解决了脏读和不可重复读,是 MySQL 的默认隔离级别。不过在某些特定场景下仍可能遇到幻读。
-
Serializable(序列化) 最高的隔离级别,强制事务串行执行。彻底解决了所有并发问题,但代价是性能开销巨大。
总结:隔离级别的选择本质上是数据一致性与系统性能的权衡。并非级别越高越好,应根据具体业务场景对并发性和准确性的要求来灵活配置。

