【发布时间】:2009-06-01 22:45:47
【问题描述】:
我们在生产 SQL Server 2000 数据库中遇到了一些非常烦人的死锁情况。
主要设置如下:
- SQL Server 2000 企业版。
- 服务器使用 ATL OLE 数据库以 C++ 编码。
- 正在通过存储过程访问所有数据库对象。
- 所有 UPDATE/INSERT 存储过程都将其内部操作包装在 BEGIN TRANS ... COMMIT TRANS 块中。
我在 Internet 上的几篇文章(如 this one)之后使用 SQL Profiler 收集了一些初始跟踪(忽略它指的是 SQL Server 2005 工具,同样的原则适用)。 从跟踪来看,这似乎是两个 UPDATE 查询之间的死锁。
我们已经采取了一些措施来降低问题发生的可能性:
- SELECT WITH (NOLOCK)。我们已将存储过程中的所有 SELECT 查询更改为使用 WITH (NOLOCK)。我们了解脏读的含义,但查询的数据并不那么重要,因为我们会进行大量自动刷新,并且在正常情况下,UI 将具有正确的值。
- 阅读未提交。我们已将服务器代码上的事务隔离级别更改为 READ UNCOMMITED。
- 缩小交易范围。我们缩短了事务的暂停时间,以最大限度地降低发生数据库死锁的可能性。
我们也质疑我们在大多数存储过程中都有一个事务(BEGIN TRANS ... COMMIT TRANS 块)。在这种情况下,我的猜测是事务隔离级别是 SERIALIZABLE,对吧?那么如果我们在调用存储过程的源代码中也指定了事务隔离级别,那适用哪一个呢?
这是一个处理密集型应用程序,我们对数据库进行了很多读取(更大的百分比)和一些写入操作。
如果这是一个 SQL Server 2005 数据库,我可以使用 Geoff Dalgas answer on an deadlock issue concerning Stack Overflow,如果这甚至适用于我遇到的问题。但目前升级到 SQL Server 2005 并不是一个可行的选择。
由于这些最初的尝试失败了,我的问题是:你会从这里开始吗?你会采取什么步骤来减少甚至避免死锁的发生,或者我应该使用什么命令/工具来更好地暴露问题?
【问题讨论】:
标签: sql-server sql-server-2000 deadlock