首页/案例库/数据库事务隔离级别
进阶数据存储

数据库事务隔离级别

脏读、不可重复读、幻读的原因与防护

数据库事务的 ACID 特性中,隔离性(Isolation)决定了并发事务如何相互影响。SQL 标准定义了四种隔离级别:读未提交、读已提交、可重复读、可串行化。级别越高,一致性越好但并发性能越差。本案例剖析各种并发问题(脏读、不可重复读、幻读)的成因,以及不同数据库的隔离级别实现差异。

数据库事务隔离级别MVCC并发控制
STEP_1
隔离级别越高,防止的问题越多,但并发性能越差
脏读、不可重复读、幻读 — PROCESSING
concurrency-problems.log
-- 脏读示例
-- 事务 A                          -- 事务 B
BEGIN;                              BEGIN;
UPDATE accounts 
  SET balance = 1000 
  WHERE id = 1;
                                    -- 读到未提交的 1000(脏读)
                                    SELECT balance FROM accounts WHERE id = 1;
ROLLBACK;  -- 回滚!
                                    -- 事务 B 读到的 1000 是无效的
                                    COMMIT;

-- 不可重复读示例
-- 事务 A                          -- 事务 B
BEGIN;
SELECT balance FROM accounts 
  WHERE id = 1;  -- 返回 500
                                    BEGIN;
                                    UPDATE accounts 
                                      SET balance = 800 
                                      WHERE id = 1;
                                    COMMIT;
SELECT balance FROM accounts 
  WHERE id = 1;  -- 返回 800 😱
-- 同一事务内,同一行数据变了
COMMIT;

-- 幻读示例
-- 事务 A                          -- 事务 B
BEGIN;
SELECT COUNT(*) FROM orders 
  WHERE date = '2024-01-01';  -- 返回 10
                                    BEGIN;
                                    INSERT INTO orders (date, amount) 
                                      VALUES ('2024-01-01', 100);
                                    COMMIT;
SELECT COUNT(*) FROM orders 
  WHERE date = '2024-01-01';  -- 返回 11 😱
-- 同一查询,结果集行数变了
COMMIT;

并发问题脏读(Dirty Read):读到其他事务未提交的数据,如果那个事务回滚,读到的就是「脏」数据。不可重复读(Non-repeatable Read):同一事务内两次读取同一行,结果不同(被其他事务修改)。幻读(Phantom Read):同一事务内两次相同查询,结果集行数不同(被其他事务插入/删除)。

实时沙盒SANDBOX
FAULT_INJECTED
快速场景
手动调节
隔离级别
事务隔离级别
使用选定的隔离级别
数据库
实现差异
使用选定的数据库
并发事务数
模拟并发
4
并发适中
显示锁信息
隐藏锁信息