我认为为交易选择隔离级别取决于交易的性质。但到目前为止,我已经看到建议使用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来保证一致性结果,否则它将受到事务调度程序的支配。
答案 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
中,第一个查询会返回0
和1,000,000
之间的任意数字。