看来今天又要倒霉了。我们最近更新了我们的 SQL 框,它拥有大量内核和内存,但我们仍使用旧的数据库模式,这简直是垃圾。
我们的旧 SQL 框有问题,但是与我们使用新 SQL 框时遇到的问题不同,尽管在推出的那天它运行得非常快,但在一周之内它就变得一团糟......
我们的 .net 应用程序有几百人左右使用,它在 SQL 框中产生大量死锁和超时,我们正在努力找出原因。我们检查了所有索引,它们现在尽可能好。一些主要表太宽,并且有大量触发器,但我们现在对此无能为力。
对于同一个用户多次尝试,许多 pid 似乎都相同。
例如...
User: user1
Time: 09:21
Error Message: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
User: user1
Time: 09:22
Error Message: Transaction (Process ID 76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
ETC....
当我们将数据库移至新箱时,它会从旧箱中备份并恢复到新箱中。
如果有人对我们可以做些什么有任何建议,我会给他们买几品脱的啤酒。
答案1
这实际上更像是一个开发问题。您可能需要咨询开发人员以确定正在使用的事务隔离级别。
Microsoft SQL Server 默认隔离级别为“已提交读”。开发人员应该了解并为事务设置适当的级别。通常建议使用尽可能限制最少的隔离级别,并尽可能避免使用“可重复读”和“可序列化”隔离级别。
如果他们使用比默认隔离级别更严格的隔离级别,例如可重复读取或可序列化,那么应用程序将更容易出现锁定问题。如果他们使用比默认隔离级别更严格的隔离级别,并且没有意识到自己在这样做,情况会更糟。
Microsoft 的顶级数据访问技术 Entity Framework 默认使用 Serializable 隔离级别。这方面的文档记录或披露并不完善。如果应用程序使用 Entity Framework,而开发人员不知道这一事实,则开发人员可能需要检查数据库设计,以确定是否可以将事务隔离级别设置为 Read Committed。
更多信息:
设置事务隔离级别 (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms173763.aspx
Entity Framework 4.0 中的事务和连接
http://blogs.u2u.be/diederik/post/2010/06/29/Transactions-and-Connections-in-Entity-Framework-40.aspx
答案2
我不喜欢啤酒,但你应该认真看看 SQL Server 分析器 - 它是分析工作量的有价值的工具,其中包括一些有助于找出死锁原因的工具。
关于这个话题有很多文章,这个足够全面。MSDN 上的官方文档也包含一些信息,尽管写得不是那么好。
答案3
如果你有适当的索引,那么没有好的办法可以解决这个问题,除非修复数据库架构和/或查询:特别是,使用 SNAPSHOT ISOLATION 和 READ COMMITTED SNAPSHOT 进行测试. 它们不是快速解决办法。
如果你不介意把这头新野兽变回一只慢猪,你可以禁用并行性。尚不确定这能有多大帮助。
最终,频繁出现死锁是由于数据库设计不充分造成的,并且没有办法解决这个问题。
答案4
您至少能记录下导致问题的查询吗?我的经验是,绝大多数问题都是由极少数查询引起的。
从错误消息来看,您运行的是 SQL Server。如果您运行的是 2005 或更高版本,请打开跟踪标志 1222,DBCC TRACEON (1222, -1)
它应该会为您提供有关查询的一些信息。糟糕的架构可能会导致问题,但我从未见过糟糕的架构直接导致死锁。通常有一个解决方法。慢速查询比导致持续死锁的查询要好得多。
删除一些造成干扰的查询,我们也许能够建议对它们进行一些修改。