MySQL 事务隔离级别
在数据库中,脏读、幻读和不可重复读是并发控制相关的概念,它们描述了在并发环境下数据访问可能出现的不同问题。为了保证数据的准确性和一致性,数据库通常会通过事务隔离级别来解决这些问题。
1. 脏读(Dirty Read)
脏读指的是一个事务读取了另一个未提交事务所更改的数据。假设有两个事务:事务A和事务B。
- 过程:事务A修改了一条数据但未提交,事务B读取了这条未提交的数据。
- 问题:如果事务A随后回滚,事务B读取的数据将失效,导致数据不一致。
示例:
事务A将某个用户的余额从100元改为200元,但尚未提交。此时事务B读取到余额为200元,但若事务A回滚,余额又恢复为100元,事务B的读取结果就不正确了。
2. 不可重复读(Non-repeatable Read)
不可重复读是指在一个事务中,多次读取同一条记录得到的结果不同。不可重复读关注的是同一条记录的修改问题。
- 过程:事务A读取一条记录的值,事务B随后修改了该记录并提交,再次读取时,事务A得到的值与前一次不同。
- 问题:事务A在同一事务中多次读取同一数据,却发现数据不一致。
示例:
事务A第一次读取某用户余额为100元。此时事务B将余额改为200元并提交,事务A第二次读取余额时发现变成了200元,这种情况称为不可重复读。
3. 幻读(Phantom Read)
幻读是指一个事务读取了某个范围的数据集后,另一个事务又在该范围内插入了新的数据,导致前一个事务在之后的查询中发现了“幻影”般的新数据。幻读关注的是记录的新增或删除问题。
- 过程:事务A读取符合某一条件的数据集,事务B随后在此条件范围内插入一条新记录,事务A再次查询时发现多了一条“幻影”记录。
- 问题:事务A前后两次查询得到的数据集不一致。
示例:
事务A查询工资高于5000元的员工,共查到10条记录。此时事务B插入了一条工资为6000元的员工记录并提交。事务A再次查询时发现多了一条记录,这就是幻读。
隔离级别与并发问题的关系
为了解决这些并发问题,数据库提供了不同的事务隔离级别:
- 读未提交(Read Uncommitted):最低隔离级别,允许脏读、不可重复读和幻读。
- 读已提交(Read Committed):允许不可重复读和幻读,防止脏读。
- 可重复读(Repeatable Read):防止脏读和不可重复读,但可能会有幻读。在MySQL InnoDB中通过间隙锁(Gap Lock)解决幻读问题。
- 串行化(Serializable):最高隔离级别,完全避免脏读、不可重复读和幻读,但会降低并发性。
不同的隔离级别在性能和数据一致性之间进行了权衡,具体选择通常视业务需求而定。
License:
CC BY 4.0