数据库访问时可能发生的问题
1.脏读(dirty read)
T1正在对一条数据进行更新,但尚未提交,此时T2读取了这条未提交的数据。稍后T1可能撤销了更新,T2读到的就是脏数据。
2.更新丢失(lost update)
T1、T2同时修改一条数据,假设它们读到的A=16,T1对A减1,并提交,A=15。T2也对A减1,由于T2读到的A为16,因此提交后A依然等于15,这样对A进行了两次减,结果却只减了1,T1的更新被丢失了。
3. 无法重复读(non-repeatable read)
T1读取了一条数据,并没有结束。此时T2对此条数据进行了更新。而后,T1再次按照同样的条件查询到这条数据时,得到了不同的内容,产生了无法重复读。
4.幻影读(phantom read)
T1对表进行多次查询,同时T2对表进行插入操作,T1每次返回不同的结果集, 如同发生了幻影。
ANSI SQL92定义了4个事务隔离级别用来解决这些问题
Level0 未提交读(read uncommitted)
不解决任何问题。
Level1 提交读(read committed)
确保事务读到的数据都是更新已提交的数据。方法是进行更新的事务对行加锁,在提交前不释放。
Level2 重复读(repeatable read)
确保事务在反复进行相同条件查询时,每次得到的数据都相同。方法是进行查询的事务对记录加锁,并在查询后不释放,直到事务结束后再释放。
Level3 序列化(serializable)
最高级别隔离。不允许事务并发,事务必须顺序执行,可避免所有问题。但需要最多的资源。
1.脏读(dirty read)
T1正在对一条数据进行更新,但尚未提交,此时T2读取了这条未提交的数据。稍后T1可能撤销了更新,T2读到的就是脏数据。
2.更新丢失(lost update)
T1、T2同时修改一条数据,假设它们读到的A=16,T1对A减1,并提交,A=15。T2也对A减1,由于T2读到的A为16,因此提交后A依然等于15,这样对A进行了两次减,结果却只减了1,T1的更新被丢失了。
3. 无法重复读(non-repeatable read)
T1读取了一条数据,并没有结束。此时T2对此条数据进行了更新。而后,T1再次按照同样的条件查询到这条数据时,得到了不同的内容,产生了无法重复读。
4.幻影读(phantom read)
T1对表进行多次查询,同时T2对表进行插入操作,T1每次返回不同的结果集, 如同发生了幻影。
ANSI SQL92定义了4个事务隔离级别用来解决这些问题
Level0 未提交读(read uncommitted)
不解决任何问题。
Level1 提交读(read committed)
确保事务读到的数据都是更新已提交的数据。方法是进行更新的事务对行加锁,在提交前不释放。
Level2 重复读(repeatable read)
确保事务在反复进行相同条件查询时,每次得到的数据都相同。方法是进行查询的事务对记录加锁,并在查询后不释放,直到事务结束后再释放。
Level3 序列化(serializable)
最高级别隔离。不允许事务并发,事务必须顺序执行,可避免所有问题。但需要最多的资源。
隔离级别 | 脏读 | 不可重复读 | 幻影读 |
未提交读(read uncommitted) | 可发生 | 可发生 | 可发生 |
提交读(read committed) | 可避免 | 可发生 | 可发生 |
重复读(repeatable read) | 可避免 | 可避免 | 可发生 |
序列化(serializable) | 可避免 | 可避免 | 可避免 |