先认异常:脏读、不可重复读、幻读不是一回事
脏读的关键词是“未提交”。事务 A 修改了数据但还没提交,事务 B 就读到了这个临时结果;如果 A 后面回滚,B 读到的就是脏数据。题干只要强调读到了未提交数据,方向就很明确。
不可重复读看的是同一行数据。事务 A 第一次读某条记录,事务 B 修改并提交了这条记录,A 再读同一条记录发现值变了。幻读看的是满足某个条件的记录集合,前后查询时多出或少了行。一个看同一行,一个看一批行,这个边界很重要。
| 并发异常 | 题干关键词 | 老师提醒 |
|---|---|---|
| 脏读 | 读到未提交数据 | 核心是未提交 |
| 不可重复读 | 同一行前后值不同 | 核心是行被修改 |
| 幻读 | 同一条件前后行数变化 | 核心是新增或删除满足条件的行 |
| 丢失更新 | 两个事务互相覆盖修改 | 更偏更新冲突,不要和读异常混 |
隔离级别不是越高越随便选
隔离级别越高,并发异常越少,但系统并发性能通常会受到更大影响。所以题目如果问“至少需要什么隔离级别”,就要选能解决问题的最低合适级别,而不是看到安全就直接选串行化。
读已提交通常可以避免脏读,但不可重复读和幻读还可能出现;可重复读能让同一行多次读取保持一致,但不同数据库实现对幻读处理可能有差异;串行化最严格,把并发效果尽量变成串行执行,但代价也最大。软考题一般考概念层面的对应关系,不会深入某个数据库产品细节。
| 隔离级别 | 大致能力 | 常见理解 |
|---|---|---|
| 读未提交 | 可能出现脏读 | 隔离性最弱 |
| 读已提交 | 避免脏读 | 每次只读已提交结果 |
| 可重复读 | 同一行多次读保持一致 | 重点防不可重复读 |
| 串行化 | 隔离性最强 | 并发性能代价最大 |
做题时按异常倒推级别
如果题干问的是避免读到未提交数据,想到读已提交及以上;如果题干强调同一事务中反复读取同一行要一致,想到可重复读及以上;如果题干强调范围查询不能出现新插入的满足条件记录,通常要往更高隔离或锁范围的方向考虑。
这里不要把 ACID 的隔离性写成一句空话。隔离性落到题目里,就是这些具体可观察的问题。能把脏读、不可重复读、幻读分别识别出来,隔离级别题就不再靠感觉。
小例子
事务 A 查询库存数量为 10。
事务 B 把库存改成 8 并提交。
事务 A 再查同一行变成 8,这更像不可重复读,不是脏读。
备考时和 ACID、锁、MVCC 放在一起看
事务隔离不是孤立点。ACID 里 Isolation 讲原则,隔离级别讲取舍,锁和 MVCC 讲实现思路。软考不一定考得很深,但会用生活化场景考你是否能分清异常类型。
复习建议是先背一句话:未提交是脏读,同一行变了是不可重复读,范围行数变了是幻读。再把隔离级别从低到高排一遍。这个顺序比直接背表格更稳。