MySQL的事务隔离级别
个人博客
- 基于MySQL8
1、并发事务带来的问题
- 脏读(Dirty read)
- 丢失修改(Lost to modify)
- 不可重复读(Unrepeatableread)
- 幻读(Phantom read)
2、事务隔离级别
- READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
- READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
- REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
在使用一些持久层框架时,同一个事务多次查询结果一致是因为缓存,而非可重复读的体现。
2.1、如何防止丢失修改
- SERIALIZABLE: 设置该隔离级别会使CRUD所有操作影响的行数据带上锁(其它隔离级别只有update操作才会上锁),其它事务必须等待锁释放才可继续执行。
- 写锁: 直接使用
update table set xx=xx+1
- 悲观锁: 在查询语句后面加上
for update
,适合update多于select操作。 - 乐观锁: 在表中维护1个version字段,每次更新+1,如果该条记录version与查询时不一致则回滚当前操作避免丢失修改,适合读多写少的场景。
2.2、查看事务隔离级别
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。我们可以通过SELECT @@tx_isolation;
命令来查看,MySQL 8.0 该命令改为SELECT @@transaction_isolation;
2.3、设置隔离级别
1 | SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE] |
2.4、手动控制事务
START TARNSACTION |BEGIN:
显式地开启一个事务。COMMIT:
提交事务,使得对数据库做的所有修改成为永久性。ROLLBACK:
回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
参考链接
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 赵晓斌技术博客!
评论