SQL快照隔离限制

Jas*_*ban 5 sql-server-2005 sql-server-2008

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

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

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

谢谢,

贾森

Aar*_*ght 10

对于那些还不是锁定和数据库实现专家的人来说,这可能是一个令人惊讶的难题.

我强烈建议您阅读Hugo Kornelis(SQL Server MVP)关于快照隔离的这一系列帖子.到目前为止,这是我在使用快照时看到的最完整的实际考虑因素.

总结主要问题:

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

根据您编写查询的方式,您甚至可能不需要使用触发器来结束意外或不一致的结果.

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

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

更新:在应用程序级别的替代品上

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

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

  • 在我看来,学习 READ UNCOMMITTED 仅用于极端的边缘情况。如果你真的围绕 READ UNCOMMITTED 构建了一个系统,享受噩梦的乐趣,我希望我的个人数据不在你的系统上。不使用它的原因有很多。除了脏读之外,它还会产生不可预测的结果。我唯一使用它的时候是当我有一个巨大的事务泵入数据并且我想要粗略计算有多少记录已经进入时。我做这个临时的。从任何 SQL Server 专家那里读一读,看看他们是怎么想的。 (2认同)