事务隔离和锁是数据库并发控制的两个核心机制,二者紧密关联但职责不同:
事务隔离定义了事务之间的可见性规则(即“看到什么数据”),而锁是实现这些规则的技术手段(即“如何保证数据安全”)。
事务隔离级别由SQL标准(ANSI/ISO)定义,从低到高分为:
不同数据库的默认隔离级别不同:
- MySQL InnoDB默认 可重复读(通过MVCC+锁实现)。
- Oracle/PostgreSQL默认 读已提交。
锁是实现隔离级别的底层工具,不同隔离级别对锁的依赖程度不同:
隔离级别 | 锁的用途 | 典型问题 |
---|---|---|
读未提交 | 几乎不加锁(仅写操作加排他锁,读不阻塞) | 脏读、不可重复读、幻读 |
读已提交 | 写操作加排他锁(X锁),读操作不加锁(通过MVCC或短持有S锁) | 不可重复读、幻读 |
可重复读 | 写操作加X锁,读操作利用MVCC或多版本快照(或长持有S锁) | 幻读(部分数据库如MySQL通过间隙锁解决) |
串行化 | 所有读操作加共享锁(S锁),写操作加X锁,可能使用范围锁(如间隙锁) | 无并发问题,但性能最低 |
不同隔离级别对锁的需求不同:
隔离级别 | 事务A操作 | 事务B操作 | 结果 |
---|---|---|---|
读未提交 | SELECT * FROM t |
UPDATE t SET ... |
A可能读到B未提交的脏数据 |
读已提交 | SELECT * FROM t |
UPDATE t SET ... |
A只能读到B提交后的数据 |
可重复读 | SELECT * FROM t |
UPDATE t SET ... |
A始终读到事务开始时的快照数据 |
串行化 | SELECT * FROM t |
UPDATE t SET ... |
B的UPDATE可能被阻塞(若A持有S锁) |
理解二者的关系,有助于根据业务需求权衡 一致性 和 并发性能。