事务A:UPDATE account SET balance = balance - 100 WHERE id = 1; -- 未提交 事务B:SELECT balance FROM account WHERE id = 1; -- 读取到未提交的数据 事务A:ROLLBACK; -- 回滚,事务B读取的数据无效
3.2 不可重复读(Non-Repeatable Read)
定义:在同一个事务中,多次读取同一数据,结果不一致。
问题:由于其他事务的修改或删除操作,导致同一事务内读取结果不同。
示例:
1 2 3
事务A:SELECT balance FROM account WHERE id = 1; -- 读取到 1000 事务B:UPDATE account SET balance = 2000 WHERE id = 1; COMMIT; 事务A:SELECT balance FROM account WHERE id = 1; -- 读取到 2000,结果不一致
3.3 幻读(Phantom Read)
定义:在同一个事务中,多次执行相同的查询,返回的记录数不一致。
问题:由于其他事务的插入或删除操作,导致同一事务内查询结果集发生变化。
示例:
1 2 3
事务A:SELECT COUNT(*) FROM account WHERE balance > 1000; -- 返回 5 条 事务B:INSERT INTO account VALUES (6, 1500); COMMIT; 事务A:SELECT COUNT(*) FROM account WHERE balance > 1000; -- 返回 6 条,出现幻读
3.4 丢失更新(Lost Update)
定义:两个事务同时修改同一数据,后提交的事务覆盖了先提交事务的修改。
问题:先提交的修改丢失。
示例:
1 2 3 4
事务A:UPDATE account SET balance = balance + 100 WHERE id = 1; -- balance = 1100 事务B:UPDATE account SET balance = balance + 200 WHERE id = 1; -- balance = 1200 事务A:COMMIT; 事务B:COMMIT; -- 最终 balance = 1200,事务A的 +100 丢失
4. 事务隔离级别
SQL 标准定义了四个事务隔离级别,MySQL InnoDB 引擎支持所有这些级别。
4.1 READ UNCOMMITTED(读未提交)
特点
隔离程度:最低
并发性能:最高
锁机制:不使用锁,直接读取最新数据
解决的问题
无:不解决任何并发问题
存在的问题
✅ 脏读:可能读取到未提交的数据
✅ 不可重复读:可能发生
✅ 幻读:可能发生
✅ 丢失更新:可能发生
使用场景
几乎不使用,因为数据一致性无法保证
仅用于对数据一致性要求极低的场景
示例
1 2 3 4
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; BEGIN; SELECT balance FROM account WHERE id =1; -- 可能读取到未提交的数据 COMMIT;
4.2 READ COMMITTED(读已提交)
特点
隔离程度:较低
并发性能:较高
锁机制:使用行锁,读取已提交的数据
MVCC:每次读取都生成新的 ReadView
解决的问题
✅ 脏读:解决了脏读问题,只读取已提交的数据
存在的问题
❌ 不可重复读:可能发生(因为每次读取都生成新的 ReadView)
❌ 幻读:可能发生
❌ 丢失更新:可能发生
使用场景
Oracle 数据库的默认隔离级别
适合对数据一致性要求不高的读多写少场景
示例
1 2 3 4 5 6
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN; SELECT balance FROM account WHERE id =1; -- 读取已提交的数据,不会脏读 -- 其他事务提交后 SELECT balance FROM account WHERE id =1; -- 可能读取到不同的值(不可重复读) COMMIT;
-- 事务B INSERT INTO account VALUES (6, 1500); -- 被阻塞,直到事务A提交
示例
1 2 3 4 5 6
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; SELECT balance FROM account WHERE id =1; -- 读取到 1000 -- 其他事务修改并提交 SELECT balance FROM account WHERE id =1; -- 仍然读取到 1000(可重复读) COMMIT;
4.4 SERIALIZABLE(串行化)
特点
隔离程度:最高
并发性能:最低
锁机制:使用表级锁或严格的锁机制,事务串行执行
MVCC:禁用,使用锁机制
解决的问题
✅ 脏读:完全解决
✅ 不可重复读:完全解决
✅ 幻读:完全解决
✅ 丢失更新:完全解决
存在的问题
❌ 性能问题:并发性能最低,可能导致大量事务等待
❌ 死锁风险:锁竞争激烈,容易产生死锁
使用场景
对数据一致性要求极高的场景
可以接受低并发的业务场景
金融、支付等关键业务
示例
1 2 3 4 5
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN; SELECT*FROM account WHERE balance >1000; -- 自动加锁,其他事务无法修改 -- 所有相关操作串行执行 COMMIT;