c# - TransactionScope 提前完成

标签 c# sql-server ado.net deadlock transactionscope

我有一个在 TransactionScope 中运行的代码块,在这个代码块中我对数据库进行了多次调用。选择、更新、创建和删除整个范围。当我执行删除时,我使用 SqlCommand 的扩展方法执行它,如果它死锁,它将自动重新提交查询,因为此查询可能会遇到死锁。

我相信当遇到死锁并且函数尝试重新提交查询时会出现问题。这是我收到的错误:

The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements.

这是执行查询的简单代码(以下所有代码都在 TransactionScope 的使用范围内执行):

using (sqlCommand.Connection = new SqlConnection(ConnectionStrings.App))
{
    sqlCommand.Connection.Open();
    sqlCommand.ExecuteNonQueryWithDeadlockHandling();
}

这是重新提交死锁查询的扩展方法:

public static class SqlCommandExtender
{
    private const int DEADLOCK_ERROR = 1205;
    private const int MAXIMUM_DEADLOCK_RETRIES = 5;
    private const int SLEEP_INCREMENT = 100;

    public static void ExecuteNonQueryWithDeadlockHandling(this SqlCommand sqlCommand)
    {
        int count = 0;
        SqlException deadlockException = null;

        do
        {
            if (count > 0) Thread.Sleep(count * SLEEP_INCREMENT);
            deadlockException = ExecuteNonQuery(sqlCommand);
            count++;
        }
        while (deadlockException != null && count < MAXIMUM_DEADLOCK_RETRIES);

        if (deadlockException != null) throw deadlockException;
    }

    private static SqlException ExecuteNonQuery(SqlCommand sqlCommand)
    {
        try
        {
            sqlCommand.ExecuteNonQuery();
        }
        catch (SqlException exception)
        {
            if (exception.Number == DEADLOCK_ERROR) return exception;
            throw;
        }

        return null;
    }
}

错误发生在线路上:

sqlCommand.ExecuteNonQuery();

最佳答案

不要忘记从您的 TransactionScope 中抑制您的选择语句。在 SQL Server 2005 及更高版本中,即使您使用 with(nolock),仍然会在 select 接触的那些表上创建锁。看看这个,它会告诉你 how to setup and use TransactionScope .

using(TransactionScope ts = new TransactionScope 
{ 
  // db calls here are in the transaction 
  using(TransactionScope tsSuppressed = new TransactionScope (TransactionScopeOption.Suppress)) 
  { 
    // all db calls here are now not in the transaction 
  } 
} 

关于c# - TransactionScope 提前完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2921920/

相关文章:

c# - Xamarin.Android JSON.Net 序列化仅在 4.2.2 设备上失败 TimeZone Not Found 异常

mysql - SQL 中的字符串操作问题从逗号分隔字符串中删除下划线和其后的字符

c# - ado.net并发冲突如何解决

c# - DataAdapter.Fill 性能异常

c# - SqlCommand 还是 SqlDataAdapter?

c# - 如何创建一个用线条连接两个列表项的控件?

c# - 在 C# : "...could not find the object..." 中从 Excel 读取错误

c# - System.Management 命名空间中是否不再提供 ManagementEventWatcher 类?

sql - 在 t-sql 中获取每隔一行作为结果表

sql - 使用 OPENXML 从 XML 中删除回车符号