当数据库上有多个事务同时执行的时候,就可能出现问题:数据库
为了解决这些问题,就有了“隔离级别”的概念,包括:ide
下面咱们来解决3个问题:线程
示例:3d
在这个例子中根本不存在 id 为 1,而且 age 为 21 的记录,事务1读到了脏数据。日志
这就是脏读,一个事务中读到了另外一个事务修改但未提交的数据。code
示例:blog
不可重复读就是一个事务中读取2次同一条记录,但每次读取的结果不一样。事务
示例:同步
幻读就是在一个事务中一样的查询条件产生取得的结果不一样,有新纪录产生了。it
幻读其实就是不可重复读的一个特殊状况。
下面假设一个场景,看看不一样隔离级别时的返回结果。
有一个表 T
,有一个int型字段 c
,包含一条记录 1
。
不一样隔离级别下的值:
V1=2,此级别下事务2的更改能够被事务1看到。
V2 和 V3 一样为 2。
V1=1,V2=2,此级别下事务2未提交的变动事务1看不到,提交后事务1能够看到。
V3=2。
V1=1,V2=1,此级别下事务1执行期间看到的值一致。
V3=2。
事务2会被锁住,等待事务1提交。V1=1,V2=1,V3=2。
不一样事务能够看到不一样的值,这是怎么实现的呢?
有一个重要概念 ”回滚日志”。
MySQL中,每条记录在更新的时候都会记录一条回滚操做记录,经过回滚操做,能够获得之前某一状态的值。
例如一个值从1依次修改到4,回滚日志就相似以下的形式:
从1改成2 <- 从3改成2 <- 从4改成3 <- 当前值为4
还有一个重要概念 “视图 read-view“,事务启动时就会建立视图,与回滚日志对应起来。
例如3个事务,产生了3个视图 A B C,和回滚日志的对应关系以下:
那么事务A取得的值始终为1,其余事务同理。即便有一个新的线程把值从4改为了5,也对其余事务没影响。