SQL快照隔离限制

时间:2009-12-31 21:22:27

标签: sql-server-2005 sql-server-2008

对于我的数据库应用程序,对某些查询的事务采用快照隔离似乎非常适合解决其中一个关键要求。

我很担心,一旦我们开始获得非常高的数量,选择快照隔离(我相信必须在数据库范围内启用)的方式现在会让我们感到困惑。快照隔离的成本是多少?它是固定成本,线性还是几何?

如果我关注大量产品,是否有类似于快照隔离的应用程序级功能的策略/模式可能具有更好的整体性能,但需要更多时间/专业知识来实现​​?

谢谢,

杰森

2 个答案:

答案 0 :(得分:10)

对于那些尚未成为锁定和数据库实施专家的人来说,这可能是一个令人惊讶的困难主题。

我强烈建议您阅读Hugo Kornelis(SQL Server MVP)的series of posts on snapshot isolation。到目前为止,这是我在使用快照时看到的实用注意事项的最完整分析。

总结主要问题:

  • 当并发事务的特定组合可以违反约束(UNIQUE,FOREIGN KEY等)时,SQL Server将回归旧的做事方式。显然,这对可靠性有好处,但不是性能。快照不是灵丹妙药,它们不能代替良好的数据库/查询设计和智能锁管理。
  • 快照和触发器可能无法很好地协同工作。如果使用触发器来保护数据完整性,则会特别危险,但即使您不这样做,几乎所有触发器都必须能够识别快照。

根据您编写查询的方式,您甚至可能不需要使用触发器来结束unexpected or inconsistent results

我不知道成本是固定的还是线性的,尽管它们绝对不是几何的;我知道无论如何都有点头疼。它经常被人们称之为“即发即忘”的选择,但事实是,如果你不知道自己在做什么,那么你最终可能会遇到重大变化(你可能不会发现这些变化)直到为时已晚!)。

如果您确定它不会导致任何其他问题,请务必使用它。但是,如果你的任何逻辑不关心脏读(这适用于许多系统中超过一半的SELECT查询),那么READ UNCOMMITTED会得到更好的结果(这涉及到更多“专业知识” - 你必须仔细考虑可能发生的事情和时间。

更新:关于应用级替代方案

唯一让人想到的就是缓存。一些数据框架可以为您(NHibernate,EF)执行此操作,在某些情况下,您甚至可能具有第三层缓存,例如基于消息输入缓存结果的Web服务,可能基于多个查询的结果。我不会真的称之为“替代”,但我想如果这些是只读查询并且基础数据不经常更改,某种形式的缓存在您的情况下会有效。当然,设计考虑因素是,相对于您需要服务的数量,您可以承受多少数据缓存;如果系统大规模并发,则可能无法扩展。

除此之外,我个人不会选择尝试实现我自己的应用级事务“层”。也许有些人已经做到了这一点,但我认为我的有限经验无论如何都无法与数百或数千名在DBMS工作20年的最聪明的设计师竞争。

答案 1 :(得分:1)

快照隔离意味着比其他隔离级别更具读取性能。通过将数据隔离到快照中,事务不需要获取行上的锁,这可以防止阻塞和死锁。

但是,它必须将行版本控制信息写入tempdb数据库。因此,对于每个事务,都应该有一些写入时间。

就像其他一切一样,你的情况将决定这对你来说是否会有更多或更少的表现。如果您的应用程序是OLTP样式,那么如果您的事务容易出现死锁,那么性能可能会大幅提升。