【问题标题】:Does the transaction underlying a SqlTransaction or a TransactionScope get rolled back if a process terminates unexpectedly?如果进程意外终止,SqlTransaction 或 TransactionScope 下的事务是否会回滚?
【发布时间】:2015-04-14 15:53:38
【问题描述】:

我正在编写一个应用程序来更新单独但相关的数据库表中的数据。我想在我的代码中的事务中执行更新查询。我知道有两种可能的方法:

我的问题是:如果进程在中间终止,即如果有人真的强行终止进程,这些模型中的任何一个都会导致事务回滚吗?例如,如果我有这个使用第一个模型的代码并且在两个命令之间终止了进程,那么事务会回滚吗?

try
{
    using (var conn = new SqlConnection(connectionString))
    {
        using (var tran = conn.BeginTransaction("MyTran"))
        {
            using (var firstCommand = new SqlCommand(firstQuery, conn))
            {
                firstCommand.ExecuteNonQuery();
            }

            //PROCESS IS TERMINATED HERE.

            using (var secondCommand = new SqlCommand(secondQuery, conn))
            {
                secondCommand.ExecuteNonQuery();
            }

            tran.Commit();
        }
    }
}
catch (Exception)
{
    //do whatever.
}

或者如果我有以下代码使用第二个模型并且在两个方法调用之间终止了进程,事务是否会回滚?

try
{
    using (var scope = new TransactionScope())
    {
        MyFirstUpdate();
        //PROCESS IS TERMINATED HERE.
        MySecondUpdate();
        scope.Complete();
    }
}
catch (Exception)
{
   //do whatever.
}

我无法在 MSDN 或其他地方找到任何信息来说明这两种情况的结果。

【问题讨论】:

    标签: c# .net sql-server database transactions


    【解决方案1】:

    如果事务未提交,则回滚。终止进程会阻止应用 COMMIT,因为永远不会调用 TransactionScope.Complete,并终止将导致回滚的连接。

    【讨论】:

    • 好的,所以连接不需要“优雅地”终止,即服务器端会在连接突然孤立的情况下处理这个问题?
    • 完全正确。数据库引擎知道连接已经消失并回滚它必须做的任何事情。
    【解决方案2】:

    如果我们谈论的是突然终止一个进程,那么“回滚”逻辑都没有机会运行,也没有消息发送到服务器。这不同于一般的异常处理,finally 块通常会确保发生回滚。

    SQL Server 的行为是对连接应用超时 - 如果连接在超时之前没有发送保持活动消息,则它被认为是死的,并在 SQL Server 端关闭。如果有事务挂起,则在关联连接关闭时回滚。

    【讨论】:

      猜你喜欢
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多