在你的情况,我建议明确设置隔离级别快照 - 这将阻止通过防止锁获得在写入(插入和更新)的方式读,但那些读取仍然是“好”的读取(即不是脏数据 - 它不是一样的NOLOCK)
通常我发现,我有我的查询锁定问题,我手动控制应用的锁。例如我会使用行级锁执行更新以避免页/表级锁定,并将我的读取设置为readpast(接受我可能会错过某些数据,在某些情况下可能会好) 链接|编辑|删除|标记
EDIT--综合所有的评论到答案
作为优化过程的一部分,SQL服务器避免越来越COMMITED读取它知道没有改变一个页面上,并自动回落到较低的锁定策略。在你的情况下,sql server从可串行读取下降到可重复读取。
问:感谢有关降低隔离级别的有用信息。你能想到它首先会使用Serializable IsolationLevel的任何理由,因为我们不使用SELECT的显式事务 - 我们知道隐式事务将使用ReadCommitted?
答:默认情况下,SQL Server将使用Read Commmited(如果这是您的默认隔离级别),但如果您没有在查询中额外指定锁定策略,则基本上是对sql服务器说:“做你认为最好的,但我的首选是Read Commited“。由于SQL Server可以自由选择,因此它可以优化查询。 (sql server中的优化算法非常复杂,我自己也不完全理解它)。在事务中不显式执行不会影响sql server使用的隔离级别。
问:最后一件事,SQL Server是否会增加隔离级别(可能需要锁的数量)以优化查询似乎是合理的?我也想知道,如果它继承了上次使用的隔离级别,重用连接池是否会影响这一点?
答:Sql服务器将会这样做,称为“锁定升级”的过程的一部分。从http://support.microsoft.com/kb/323630,我引用:“Microsoft SQL Server动态地决定何时执行锁定升级。当做出这个决定时,SQL Server会考虑在特定扫描中保留的锁的数量,整个锁的数量事务,以及整个系统中用于锁定的内存。通常,SQL Server的默认行为会导致锁定升级,这些锁定升级仅发生在可以提高性能的那些点上,或者必须将过多的系统锁内存减少到更多但是,某些应用程序或查询设计可能会在不需要的时候触发锁升级,并且升级的表锁可能会阻止其他用户“。
尽管锁升级与改变隔离级别并不完全相同,但是查询运行得很好,这让我感到惊讶,因为我不希望sql server比默认隔离级别允许的更多的锁。
没问题灰。感谢有关降低隔离级别的有用信息。你能想到它首先会使用Serializable IsolationLevel的任何理由,因为我们不使用SELECT的显式事务 - 我们知道隐式事务将使用ReadCommitted? – Graham 2009-08-27 07:38:03
谢谢阿什。如果您将您的评论与答案结合起来,我会将其标记为答案并为您投票。 – Graham 2009-08-27 13:34:40
最后一件事,SQL Server是否会增加隔离级别(并且可能是所需的锁的数量)来优化查询似乎是合理的?我也想知道,如果它继承了上次使用的隔离级别,重用连接池是否会影响这一点? – Graham 2009-08-27 13:48:22