事务并发引起的问题
脏读 (Drity Read): 某个事务已更新一份数据, 另一个事务在此时读取了同一份数据, 由于某些原因, 前一个 RollBack 了操作, 则后一个事务所读取的数据就会是不正确的.
不可重复读 (Non-repeatable read): 在一个事务的两次查询之中数据不一致, 这可能是两次查询过程中间被另一个事务更新了原有的数据.
幻读 (Phantom Read): 和不可重复读很像, 在一个事务的两次查询中数据笔数不一致, 这可能是两次查询过程中间被一个事务插入了新的数据.
隔离级别
为了解决上面事务并发引起的问题, 数据库的事务系统一般提供了隔离级别的设定:
- 读未提交 Read Uncommitted, 对应值为
1
, 最低级别, 会导致脏读、不可重复读、幻读 - 读已提交 Read Committed, 设置为
2
, 避免脏读 - 可重复读 Repeatable Read, 设置为
4
, 避免脏读、不可重复读 - 可串行化 Serializable, 设置为
8
, 最高级别, 所谓串行化, 就是完全避免了并发, 脏读、不可重复读、幻读都不会发生
MySQL 默认是 4
因为数据库对隔离级别的实现有所差别, 貌似 MySQL 设置成 4 时也能避免幻读.
查看隔离级别:
select @@global.tx_isolation; -- 全局隔离级别 select @@session.tx_isolation; -- 当前会话的隔离级别
设置隔离级别 (谁读设置谁):
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }