脏读
我们通过一个products表来解释一下什么是脏读,该products表有一列quantity(数量),现在的值为20。假如现在有两个事务T1和T2,它们都是要更新quantity列,T1将该列值加100,T2将此列减10,但是T1执行失败进行了回滚。我们很容易计算出正确的结果20-10=10,但是如果事务按照以下方式运行,能够得出什么结果?
时间 事务 步骤 存储值
1 T1 读出quantity的值 20
2 T1 quantity=20+100 120
3 T1 写入quantity值 120
4 T2 读出quantity(T1未提交) 120
5 T2 quantity=120-10 110
6 T1 回滚(rollback) 20
7 T2 写入quantity值 110
以上得出了110的结果,显然是不正确的,问题就在于T2读取到了T1没有提交的数据,我们把这种情况就称之为脏读。
不可重复读
还是事务T1和T2,它们都是要更新quantity列,T1将该列值加100,T2将此列减10,而且两个事务都成功。我们很容易计算出正确的结果20+100-10=110,但是如果事务按照以下方式运行,能够得出什么结果?
时间 事务 步骤 存储值
1 T1 读出quantity的值 20
2 T2 读出quantity的值 20
3 T1 quantity=20+100 120
4 T2 quantity=20-10 10
5 T1 写入quantity值(更新丢失) 110
6 T2 写入quantity值 10
得出了10的结果,仍然是不正确的。问题就在于T2的值覆盖了T1的值,我们把这种情况称之为不可重复读。
幻觉读
例如T1对一个表中的所有行修改,同时T2向该表中插入一行记录。这时在T1中就会发生还有没有被修改的数据行,就好象发生了幻觉一样。
SQL92标准定义了四种隔离级别,以解决以上问题,四种隔离级别如下图所示: