开门见山
可重复读仅能保证再次执行同样的查询时,先前返回【过】的结果一定跟之前一样,而不保证会不会多出别的记录。如果返回了之前没有出现过的记录,就是幻读。
隔离级别
数据库事务的四种隔离级别相信现在已经烂大街了,但是发现很多文章都没有解释清楚不可重复读non-repeatable read
与幻读phantom
的区别,所以这里总结明确一下。
-
读未提交(Read Uncommitted)
这个非常好理解,就是在一个事务中可以读到其他事务还没有提交的中间值,相当于没有隔离。
-
提已提交(Read Committed)
相对于上一条而言,此级别在一个事务中只允许读到其他事务已经提交过的值,看不到其他事务的中间值。但这样也有问题,就是在同事务中前后两次select有可能会返回不同的结果,即第一次select以后,如果中间有其他事务提交了对相关数据的修改,那么第二次select就会看到新的值,与第一次select不一致。术语"不可重复读"指的就是这种情况,重复读即多次select, 不可重复读就是多次select的结果可能是不一样的。
-
可重复读(Repeatable Read)
容易混淆的地方就在这了。可重复读这一级别保证了在同一个事务中,第一次select到的数据,在后续select中仍然保持不变。重点在于,它保证的是对于第一次读到的数据,后续再对这些数据的读操作会返回相同的结果。它的问题在于范围查询。比如第一次读到了A, B两条记录,那么可重复读仅能保证再执行同样的查询时,返回的A, B记录跟之前的一样,而不保证其他记录。这里的其他记录是指在两次查询之间有其他事务在中间插入了新记录,这些新记录刚好与你的where条件匹配,这样一来虽然第二次查询也返回了跟之前一样的A, B,但可能会多了C, D, E等新记录,这就叫幻读。
-
串行化
没啥好说的。