在数据库隔离级别中READ COMMITTED优于READ UNCOMMITTED的优点是什么,或者为什么Dirty Read被认为是如此糟糕

时间:2013-04-25 08:11:11

标签: database concurrency rdbms isolation-level

我认为为交易选择隔离级别取决于交易的性质。但到目前为止,我已经看到建议使用READ_UNCOMMITTED避免(或说'限制')。大多数数据库使用READ_COMMITTED作为默认隔离级别。不知怎的,我发现自己很慢地观察READ COMMITTED优于READ UNCOMMITTED。

READ COMMITTED优于READ UNCOMMITTED的唯一优势我看到是READ COMMITTED,永远不会做DIRTY READ。我发现只有在事务ROLLBACK(从中进行脏读的事务)的情况下,DIRTY READ才能使数据库不一致。这意味着在系统的一部分中,事务ROLLBACK不太可能(或者说永远不会发生),READ UNCOMMITTED将提供比READ COMMITTED更好的性能。

让我们来看一个案例: 我们有记录A = 100; B = 200;

T1(READ_UNCOMMITTED)  |    T2
                      |    A = A + 100 //(A=200 NOW)
 READ(A); //200       |
 B = B + A //400      |
 COMMIT;              |
                      |    COMMIT;

数据库失败的唯一方法是发生事务T2'ROLLBACK'。现在,如果T2最不可能有一次ROLLBACK而不是在我看来因为性能提升而且风险很小。

提前致谢

修改的 这个评论太长了,所以@Quassnoi 假设我们有两个事务T1(会话1)和T2(会话2)。 T2将数据库从一致状态DB_S1带到DB_S2。如您所知,带有READ_UNCOMMITTED的T1可能会给出不与DB_S1或DB_S2兼容的结果。我们可以用READ_COMMITTED来说明T1。

Lets say a schedule: T1 starts, counts 100; 
T2 starts -> has updated row 1 to .9M ;
T1 starts -> counts 150
T2 starts -> finish update
T1 starts -> can't find anything where value = 1 hence finish.

T1给出的结果为150,从未存在过。

我想在这种情况下,T1需要一个Searializable Lock来保证一致性结果,否则它将受到事务调度程序的支配。

1 个答案:

答案 0 :(得分:0)

想象一下,你有一张包含1M记录的表,所有记录都有value = 1

然后同时运行这两个查询:

第1节:

SELECT  COUNT(*)
FROM    mytable WITH (NOLOCK)
WHERE   value = 1

第二节:

UPDATE  mytable
SET     value = 2
WHERE   value = 1

SQL Server中,第一个查询会返回01,000,000之间的任意数字。