事务的隔离级别



在标准的SQL规范中,定义了4个事务隔离级别。

隔离级别

未授权读取(RU)

未授权读取也被称作读未提交(Read Uncommitted),这种隔离级别允许读取未提交的数据,隔离级别最低。
RU这种隔离级别中,允许脏读, 但不允许出现丢失更新

丢失更新: 两个事务同时更新统一数据时, 会发生更新丢失。
脏读: 一个事务读取到另一个事务未提交的修改时, 会产生脏读。如:事务A把一数据从1update成2,update成3直到update成9, 事务B每次select都能看到事务A的中间值(比如2,3或7),对B来说这些就是脏数据。

授权读取(RC)

授权读取也被称为读已提交(Read Committed),这种隔离级别只允许读取已经被提交的数据。
RC这种隔离级别中允许出现不可重复读, 但不允许脏读

不可重复读: 同一查询在同一事务中多次进行,由于其他提交事务所做的 修改或删除,每次返回不同的结果集,这就发生非重复读。 如:事务A操作数据1, 要把它update成9, 事务B第一次select发现是1, 此时事务A提交了, 事务B再次select发现变成了9, 这种现象叫做不可重复读
它的危害也很明显, 因为B第一次读取的时候是1, 若果要对它进行+1在更新回去, 就会变成2, 但实际上这是不对的。(这里你不能用mysql做实验, 因为mysql不再这个隔离级别, 所以这种情况在mysql中不会发生)

可重复读取(RR)

可重复读取(Repeatable Read), 这种隔离级别保证在一个事务中,多次读取到的数据都是和事务开始时是一样的。
RR这种隔离级别允许出现幻读,但不允许不可重复读

幻读: 同一查询在同一事务中多次进行,由于其他提交事务所做的 插入 操作,每次返回不同的结果集,此时发生幻像读。在RR中, 事务B读取到的数据值都是跟事务开始时一致(所以可以重复读), 但若事务A新insert了一条数据, 事务B是可见的, 因此对于事务B来说,开始时没有这个数据,但是过了一会儿却多出来一条数据(数据不一致了),因此对于事务B来说就很莫名其妙。

MySql就是在RR隔离级别上的, 但它在此基础上又加了gap锁, 保证了不会出现幻读。其实MySql中并没有区分不可重复读幻读,MySql统称为幻读并且禁止了幻读现象的出现。

串行化(S)

串行化(Serializable)是最严格的事务隔离级别,它要求所有的事务都被串行执行。