我在这里已经读到,每行将存储一些额外的数据,因此我们可能会看到性能下降,但是还有其他风险吗?

例如。
这会影响数据库的恢复吗?
我们还需要采取其他措施来利用此功能吗?

我计划执行以下命令:

ALTER DATABASE DatabaseName SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE DatabaseName SET ALLOW_SNAPSHOT_ISOLATION ON


I相信这将使我们更接近oracle,如果一个事务正在更新,其他事务仍可以读取旧数据。这是正确的吗?

我正在研究此问题,因为我厌倦了SQL Server 2005中的锁定问题。我希望这可以减少用户偶尔看到的死锁,有助于提高应用程序的整体性能,并鼓励我们的开发人员为每笔交易执行一项以上的操作而不必担心。

#1 楼

摘要


如果遇到锁定问题,则代码有问题:不是数据库引擎
不是魔术子弹
可能会添加更多问题

加载

它也会增加tempdb和CPU的负载。另请参见:



“性能影响:Read_Committed_Snapshot的潜在成本”(Linchi Shea)

安全

最重要的是,默认情况下,快照隔离在许多情况下都不安全。阅读“快照隔离”(维基百科),以了解有关写偏斜异常的更多信息。下一节是“使快照隔离可序列化”来解决此问题。


因此,一般而言,快照隔离给用户带来了一些不小的限制,这些用户会维护非平凡的约束。可能不理解潜在的陷阱或可能的解决方案。这种传输的好处是性能更高。


另请参见:




“已提交的快照隔离快照的潜在危险级别”(JimMcLeod,在Alex Kuznetsov的评论中有争议)

已死锁!:“读取已提交的快照”解释了(Nick Berardi)

可序列化与快照隔离级别,大理石问题(Craig Freedman)

READ_COMMITTED_SNAPSHOT下涉及UDF的读取似乎不一致(Alex Kuznetsov)


#2 楼

我知道这是一个旧线程,但是我想说快照隔离在很大程度上是一个神奇的子弹。它将消除您在读者和作家之间的所有障碍。但是,这不会阻止作者阻止其他作者。

根据我的经验,TEMPDB上的额外负载可以忽略不计,并且行版本控制在减少阻塞的读者方面的好处是巨大的。

作为参考,行版本控制(快照隔离)是Oracle数十年来用于实现隔离而不阻塞读者的方法,而我研究了近20年的Oracle DB遇到的阻塞问题比SQL Server少得多。尽管大多数SQL开发人员都不愿使用快照隔离,因为他们只针对使用默认设置的数据库测试了代码。

#3 楼

要添加到其他答案中的几个其他要点:SET ALLOW_SNAPSHOT_ISOLATION ON仅在数据库中启用快照隔离。要利用它,您必须重新编码并为其申请要应用的事务。需要更改调用代码以处理更新冲突错误。

SET TRANSACTION ISOLATION LEVEL SNAPSHOT之后,读取已提交的语句将使用行版本控制。注意,这是只读的语句级行版本控制。对于更新,将检索“真实”行并应用更新锁。请参阅了解基于行版本控制的隔离级别中的“行为摘要”部分。

这两种方法,如果没有详尽的测试,很可能会给系统带来一系列全新的问题。

#4 楼


我相信这将使我们更接近oracle,如果一个事务正在更新,则其他事务仍可以读取旧的数据。这是正确的吗?


是的,这是正确的。

值得阅读gbn答案中的链接,我相信这同样适用于Oracle的默认MVCC和快照隔离模式下的SQL Server。我要补充一点,如果您了解潜在的陷阱,则IMO的收益将远远超过增加的困难(从Oracle的角度来讲)-当然,一些锁定问题也将合法化,这就是MVCC的意义(还有一类锁定由于代码问题而无法解决的问题,但是我假设您理解这一点。

#5 楼

我们在所有使用SQL Server DB的项目中都使用SNAPSHOT ISOLATION。
没有更多的1205 SQL错误,这不是由于错误的应用程序代码引起的,而是由默认的页锁定和行锁定行为引起的。

对性能的影响微乎其微,到目前为止已经过去了7年,在不同的系统中处理了数以亿计的操作,而快照分离没有任何问题。并行的单行中的关键信息非常出色,并且SNAPSHOT ISOLATION会成为任何不一致问题的原因的可能性几乎为零。

如果您有OLTP系统,则可以通过设计更新在许多线程中基于当前行数据的单行,在这种情况下当然不能接受SNAPSHOTS。