2011-09-11 48 views
3

我有一个偶尔会导致数据库死锁的WCF服务。我的服务允许您向理事会提交申请,也允许您再次加载申请,因为理事会可以更新它们。每个应用程序都有许多与之关联的文档。如何避免缓慢查询造成的死锁

所以,如果发生在我服务的一组这样的事件

1) Application #1 is submitted 
2) A document is uploaded for application #1 
3) Application #1 is loaded 
4) Part 2 above finishes 

僵局部分3.我相信原因是,在第2部分文件需要一段时间才能从提交到SQL服务器WCF服务,并在此期间锁定表。

因此,如果我们从数据库应用程序#1加载,并且遇到问题的相关文档。

我正在使用实体框架。我该如何解决这个问题?我真正想要做的就是在这种情况下加载文件,这些文件完全被提交,并且不会被锁入表格或任何东西中。

通过,这是我收到的特定错误的方式,

Message: Transaction (Process ID 93) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

更新:我有一对夫妇,我可以改变操作的顺序意见。我不能这样做,因为第2部分和第3部分来自对WCF服务的不同调用。所以服务的用户需要定购这些操作。 '要求他们改变'你说,但也不是那么简单。操作的顺序实际上取决于最终用户恰好在恰当的时刻“刷新”浏览器。

更新#2:我需要一些关于如何复制此问题的建议。我已经写了一个测试应用程序,上面的第2部分确实阻止了第3部分的操作,但对我的影响是操作3只是阻塞,直到操作2完成,然后操作3结束。

因此,这意味着第3部分需要1分50秒,而不是3分。任何想法为什么它会阻止我,而不是造成僵局?它可能与该服务器上整体数据库流量的数量有关,因为我正在使用测试服务器,或者某些数据库设置可能会影响它?

回答

1

有几种方法,以避免在一般的死锁(SQL Server等数据库):

1)只在事务结束通话saveChanges(),执行所有查询到一起。

2)更改顺序以执行数据库更新,首先执行所有读取(SELECT)并最后执行所有更新。

3)从事务中没有修改的数据的事务中读出数据。

4)如果应用程序逻辑允许,将事务的隔离级别更改为SERIALIZABLE(性能较差)或SNAPSHOT或没有像READ UNCOMMITTED这样的锁定的其他中间级别。

5)使用lock(lock_object)创建同步代码块,以避免两个线程并行执行同一事务或执行两个锁定自己的不同事务。

+0

我已经更新了这个问题。我无法真正控制操作的顺序。我的解决方案必须与你的答案的第4或5部分相关。第5部分听起来似乎不太可能,因为可能有一些线程同时运行。 – peter

+0

您可以运行多个线程,但您只需要同步执行导致死锁的操作的代码部分。这会降低整体吞吐量,但另一种选择是更改隔离级别以避免锁定。 SNAPSHOT隔离级别,SQL Server 2005中的新增功能尝试解决死锁问题;而不是在更改数据时创建锁,存储不同版本的数据,并且每个事务读取所需数据的版本。 –

+0

我已经勾选了你的答案,因为它是第一个。我认为这个问题可以得到缓解。导致死锁的查询是从数据库(blob)中拉出一个不需要的字段。这意味着通过从查询中删除该字段将使查询更快,从而在表被锁定时不太可能发生。找出真正的问题会变得更加困难,因为我所看到的确定它可能会导致阻塞,但找出实际上导致死锁的因素会变得更加复杂。 – peter

1

一对夫妇的解决方案:

  • 使用读取未提交的隔离级别,如果你不介意的话可能有未提交的行步骤3(这取决于您的情况)出现。

OR

  • 批量贵就贵EF背景下更有效地并更改确保他们执行一次全部(没有看到你的代码,我不知道你是否这样做或不)

编辑

下面的链接也可以有助于解决问题和修复您的问题:

http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx

+0

我无法控制操作的顺序。我已经更新了我的问题。我的解决方案必须与我认为的隔离级别相关。 – peter