如何在.NET 3.0 / WinForms / SQLServer 2005中避免这种阻塞情况?

时间:2008-12-25 04:22:09

标签: .net winforms sql-server-2005

申请1 -

  • 针对SQLServer 2005数据库打开SqlConnection和SqlTransaction
  • 将记录插入表1
  • 不提交或回滚SqlTransaction - 从本质上保持这个以展示/描述问题

申请2 -

  • 针对SqlServer 2005数据库打开SqlConnection和SqlTransaction
  • 尝试运行此查询 - “SELECT COUNT(Id)FROM Table1”

表1 - Id是标识字段。 Name是varchar字段。表中没有其他字段

应用程序2无法运行“SELECT ...”查询。似乎Table1被应用程序1中完成的插入锁定或阻止。

虽然上面提到的场景是虚构的 - 但它证明了我们正面临的问题。我们希望能够打开一个长时间运行的SqlTransaction(可能是几个小时),并通过该SqlTransaction进行许多插入/更新。

我们正在开发一个数据转换应用程序,在将数据插入/更新到数据库之前,必须对大量数据进行大量处理。当我们将基于WebForms的主应用程序运行在我们想要执行长时间运行事务的同一个SQLServer 2005数据库时,就会发生数据转换。

我们的应用程序中的所有表都是通过ClientMaster表中的ClientID字段进行分段的。例如,如果我们有一个CollegeMaster表,那么它将具有ClientID字段作为主键的一部分,并且ID字段用于其自己的标识。数据转换首先创建一个新的ClientID,并在所有其他表中使用新的ClientID字段。

理想情况下,应用程序2中提到的所有查询都不应受长时间运行事务的影响。这些查询应仅读取/使用已提交的数据并继续工作,而不是由于长时间运行的事务而被阻止。应用程序1可以做些什么来确保实现这一目标?

4 个答案:

答案 0 :(得分:1)

我建议没有长时间运行的交易;然而,随着说:

您可以使用提示降低事务隔离级别。我通常不推荐这种做法,但如果您选择这样做:

从Table1(NOLOCK)中选择count(id)你实际上是通过传递表上的所有锁;然而,要警告你,你可以并且最终会得到脏读,幻读(数据存在一分钟而不是下一分钟)。如果您的查询被细分,那么您应该没问题。您还可以在线阅读其他提示。

另一种选择是在登台表中执行所有长时间运行的处理,然后对table1执行一次最终复制/插入。这将有助于缩短交易时间。

答案 1 :(得分:1)

您可能需要查看此Sql 2005功能。听起来它可能对你有所帮助。 它是一个较新的锁定机制,你必须在数据库中启用,但显然阻止更少。

http://msdn.microsoft.com/en-us/library/ms177404(SQL.90).aspx

答案 2 :(得分:0)

数据转换长时间运行事务背后的原因是SQLServer 2005已经有了回滚功能。如果数据转换出现问题,我们可以使用该工具回滚插入/更新的数据。

反对登台表的原因是我们有很多身份字段,在并发情况下很难跟踪。在从实际源表转换到登台表时,我们将在“主”表中生成一组标识值,这些标识值将在“子”临时表中进一步使用。接下来,在将数据从登台表推送到目标表的同时,我们必须确保为“主”表生成的新标识值被映射并正确传播到“子”表。

答案 3 :(得分:0)

为什么不将所有更改存储在DataSet中并一次性提交所有内容?这不会解决长期运行的交易问题吗?