2026-10-22 11:00:19
定义:如果一个事务读取到了另一个未提交事务修改过的数据,就意味着发生了脏读。
脏读允许一个事务读取到另一个事务尚未提交的数据,这可能会导致数据的不一致性。例如,事务A正在修改某条记录,但尚未提交,此时事务B读取了这条记录,并基于这个未提交的数据进行了进一步的操作。如果事务A最终回滚,那么事务B基于脏数据所做的操作就会失效,导致数据不一致。
解决脏读对应的隔离级别:读已提交(READ COMMITTED)
在READ COMMITTED隔离级别下,每次读取操作前都会生成一个新的ReadView,用于判断记录的可见性。同时,在记录更新操作时会为更新的记录加上行锁,确保读取到的数据是已经提交的。

定义:如果一个事务修改了另一个未提交事务的数据(或另一个事务读取到了另一个事务已经提交的修改),就意味着发生了不可重复读。
不可重复读是指在同一个事务内,多次读取同一数据集合时,由于其他事务的修改导致读取的数据不一致。例如,事务A第一次读取某条记录后,事务B对该记录进行了修改并提交,然后事务A再次读取该记录时,发现数据已经发生了变化。
解决不可重复读对应的隔离级别:可重复读(REPEATABLE READ)
在REPEATABLE READ隔离级别下,仅在第一次读取操作时生成ReadView,并且对于记录的更新操作,会对每一条被更新的记录加上next-key锁(等价于行锁+间隙锁)。这样,在同一个事务内,无论其他事务如何修改数据,当前事务读取到的数据始终是一致的。

定义:如果一个事务先根据某个搜索条件查询出一些记录,在该事务未提交时,另一个事务写入了一些符合搜索条件的记录(指INSERT / DELETE / UPDATE操作),就意味着发生了幻读。
幻读强调的是在同一个事务内,使用相同的搜索条件多次查询记录时,后续的查询读到了之前没有读到的记录。这些之前没有读取到的记录称为“幻影记录”。幻读通常发生在范围查询中,例如使用BETWEEN、LIKE或IN等条件进行查询时。
解决幻读对应的隔离级别:可重复读(REPEATABLE READ,部分解决)
在MySQL的InnoDB存储引擎中,REPEATABLE READ隔离级别通过MVCC和next-key锁在一定程度上避免了幻读的产生。next-key锁不仅锁住了被查询的记录,还锁住了这些记录之间的间隙,防止其他事务在这些间隙中插入新的记录。然而,需要注意的是,InnoDB的MVCC并不能完全禁止幻读。在某些特殊情况下,例如当事务T1在第一次查询后,事务T2插入了新的记录并提交,然后T1再次查询时仍然可能读取到这些新插入的记录(尽管这些记录的trx_id隐藏列的值已经变成了T1的事务id)。

总结: