1

我认为为事务选择隔离级别取决于事务的性质。但据我所知,始终建议避免(或说“受限”)使用 READ_UNCOMMITTED。大多数数据库使用 READ_COMMITTED 作为默认隔离级别。不知何故,我发现自己观察到 READ COMMITTED 优于 READ UNCOMMITTED 的优势很慢。

我看到的 READ COMMITTED 优于 READ UNCOMMITTED 的唯一优势是 READ COMMITTED 将永远不会执行 DIRTY READ。我发现 DIRTY READ 只能在事务 ROLLBACK(进行脏读的事务)的情况下使数据库不一致。这意味着在事务 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 需要一个可序列化锁来保证一致性结果,否则它将受事务调度程序的支配。

4

1 回答 1

0

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

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

第 1 节:

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

第 2 节:

UPDATE  mytable
SET     value = 2
WHERE   value = 1

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

于 2013-04-25T08:15:47.137 回答