【发布时间】:2017-01-16 13:48:12
【问题描述】:
所以,我遇到了一些问题。 情况是,我们让这个遗留应用程序公开了一个 Web 服务,并接收从移动应用程序发送给它的数据。
最近我们开始收到来自用户的报告,称从移动应用程序提交数据的过程需要很长时间才能提交结果。
在检查 Web 服务日志时,我们会看到很多异常,它们指向代码中的不同方法。所有这些方法的共同点是,它们是对数据库的写操作。所有方法都是应用程序打开的更大 SQL 事务的一部分。
在开始写入数据库之前处理传入结果时,应用程序会进行大量检查和查找。一切都是通过实体框架完成的,并被包装在一个事务中。
似乎这些事务锁定了数据库,并阻止处理其他传入的结果,这导致尝试从应用程序提交结果超时并不断重试,直到最终通过大门。这只是我们的理论。
事务只是将新数据写入数据库 - 它不会修改任何现有数据。将其包装在事务中的唯一原因似乎是能够在事务失败时回滚事务——而不是在它工作时避免对表进行任何其他写入操作。
主要问题是,它是一个遗留应用程序,我们目前无法接触到以前在该应用程序上工作的任何人。因此,进行重写将非常耗时且容易出错。我们正在逐步淘汰这个特定问题,所以如果我们能给自己争取一些时间,那将是理想的。
如果我们的假设是正确的,即运行两个并行写入操作应该没有问题,是否有一种简单的方法可以允许多个这些事务同时运行而无需对应用程序进行重大重写?
【问题讨论】:
-
不要打开交易并在该交易中做所有事情。您应该只在事务中进行实际的插入/更新/删除。您可能将事务保持打开的时间过长,因此阻塞读取事务的变化很大,这会导致您的问题。
-
嗨@GuidoG,我们已经意识到这一点。问题似乎不是,我们正在阻止其他读取操作。这是事务正在阻止任何其他写入操作(自身的其他实例)。但是,正如问题中所指出的,理论上不应该有多个同时运行的问题。能以某种方式完成吗?
-
你怎么确定你没有阻塞读操作并且你只是阻塞了写操作?其他实例是否如您所说的那样?你是怎么确定的。此外,是否有其他应用程序在此数据库上进行读取/更新?他们也可能会阻塞。
-
@GuidoG,我很确定我们正在阻止读写操作。然而,主要是写操作是一个问题,因为它们似乎导致其他传入的移动应用程序由于死锁而超时。到目前为止,我们所做的是分析代码并得出结论,总而言之,让其中两个写入操作并行运行应该没有问题。它们只是将新数据写入数据库——它们是完全独立的。但是,正如你暗示的那样,我们并不完全确定。但是,如果可能的话,我们希望在测试中尝试一下。
-
我会从BrentOzarULTD's SQL Server First Responder Kit 开始,看看你的数据库出了什么问题。继续Capturing Deadlock Information
标签: c# sql-server entity-framework concurrency transactionscope