Gra*_*ham 4 sql-server-2005 isolation-level
我们的客户遇到了数据库应用程序的一些阻塞问题.我们要求他们运行阻塞进程报告跟踪,他们给我们的跟踪显示在SELECT和UPDATE操作之间发生阻塞.跟踪文件显示以下内容:
所以基本上我们不知道为什么SELECT查询的隔离级别不是默认的ReadCommitted IsolationLevel,更令人困惑的是,为什么查询的IsolationLevel会随着时间的推移而改变?只有一个客户看到此行为,因此我们怀疑它可能是数据库配置问题.
有任何想法吗?
提前致谢,
格雷厄姆
在您的场景中,我建议明确地将隔离级别设置为快照 - 这将阻止读取通过阻止锁定来阻止写入(插入和更新),但那些读取仍然是"良好"读取(即不是脏数据 - 它和NOLOCK不一样)
通常我发现我的查询锁定问题,我手动控制应用的锁.例如,我会使用行级锁进行更新,以避免页面/表级锁定,并将我的读取设置为readpast(接受我可能会错过某些数据,在某些可能正常的情况下)链接|编辑|删除|标记
编辑 - 将所有评论结合到答案中
作为优化过程的一部分,sql server避免在知道未更改的页面上获取提交读取,并自动回退到较小的锁定策略.在您的情况下,sql server从可序列化读取中删除到可重复读取.
问:感谢您提供有关降低隔离级别的有用信息.你能想到它首先会使用Serializable IsolationLevel的任何理由,因为我们没有对SELECT使用显式事务 - 我们理解隐式事务会使用ReadCommitted吗?
答:默认情况下,SQL Server将使用Read Commmited,如果这是您的默认隔离级别但是如果您不在查询中另外指定锁定策略,则基本上是对sql server说"做你认为最好的,但我的偏好是Read Commited".由于SQL Server可以自由选择,因此它可以优化查询.(sql server中的优化算法非常复杂,我自己并不完全理解它).未在事务中显式执行不会影响sql server使用的隔离级别.
问:最后一点,SQL Server是否会增加隔离级别(可能是所需的锁数)来优化查询似乎是合理的?我还想知道如果它继承了最后使用的隔离级别,重用池化连接是否会影响它?
答:Sql server会将其作为名为"Lock Escalation"的进程的一部分.从http://support.microsoft.com/kb/323630,我引用:"Microsoft SQL Server动态确定何时执行锁定升级.在做出此决定时,SQL Server会考虑特定于某个锁定的锁定数量.扫描,整个事务持有的锁的数量,以及整个系统中用于锁的内存.通常,SQL Server的默认行为导致锁升级仅在可提高性能的那些点发生或者当您必须将过多的系统锁内存减少到更合理的级别时.但是,某些应用程序或查询设计可能会在不需要时触发锁升级,并且升级的表锁可能会阻止其他用户".
虽然锁升级与更改查询运行的隔离级别不完全相同,但这让我感到惊讶,因为我不希望sql server占用比默认隔离级别允许的锁更多的锁.
| 归档时间: |
|
| 查看次数: |
9896 次 |
| 最近记录: |