Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 死锁后重新提交事务_C#_Asp.net_.net_Sql Server_Linq To Sql - Fatal编程技术网

C# 死锁后重新提交事务

C# 死锁后重新提交事务,c#,asp.net,.net,sql-server,linq-to-sql,C#,Asp.net,.net,Sql Server,Linq To Sql,我有一个代码块包装在事务作用域中。我正在使用LINQ与数据库通信。捕获死锁异常后,如何重新提交事务?基本上,您只需捕获死锁异常并重试代码。我们这样做: private static void ExecuteWithDeadlockRetry(int maxAttempts, bool useTransaction, Action action) { int tryCount = 0; string errorMessage; // If use transaction

我有一个代码块包装在事务作用域中。我正在使用LINQ与数据库通信。捕获死锁异常后,如何重新提交事务?

基本上,您只需捕获死锁异常并重试代码。我们这样做:

private static void ExecuteWithDeadlockRetry(int maxAttempts, bool useTransaction, Action action)
{
    int tryCount = 0;
    string errorMessage;

    // If use transaction is true and there is an existing ambient transaction (means we're in a transaction already)
    // then it will not do any good to attempt any retries, so set max retry limit to 1.
    if (useTransaction && Transaction.Current != null) { maxAttempts = 1; }

    do
    {
        try
        {
            // increment the try count...
            tryCount++;

            if (useTransaction)
            {
                // execute the action inside a transaction...
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    action();
                    transactionScope.Complete();
                }
            }
            else
                action();

            // If here, execution was successful, so we can return...
            return;
        }
        catch (SqlException sqlException)
        {
            if (sqlException.Number == (int)SqlExceptionNumber.Deadlock && tryCount < maxAttempts)
            {
                // Log error here
            }
            else
            {
                throw;
            }
        }
    } while (tryCount <= maxAttempts);
}
SqlDeadlockHelper.Execute(() =>
{
  // Code to execute here
}
请注意,Execute()方法最终调用ExecuteWithDeadlockRetry()。我们的解决方案比您要求的要多一些,但这应该给您一些大致的指导。

首先思考一下为什么会出现僵局?是因为您在LINQ上下文中读取并修改的值被另一个事务更改了吗?唯一合理的做法是再次读取这些值,并确定您的更改对新值是否有意义。由于这是ASP.NET,这意味着向用户显示新的值,因此您必须再次将页面返回给用户,并通知用户发生了更改,并且必须再次编辑数据


死锁时自动重新提交是可能的,但几乎总是一个坏主意。这很可能会导致数据库中出现错误状态,因为您的域规则被破坏,因为您的重试会覆盖读取该值后发生的更改。

如果您是这样,您几乎是在要求发生死锁!使用explicit将隔离级别更改为远离…为什么要使用transactionscope。您是否有多个提交更改?9/10倍,这是不必要的。