如果进程意外终止,SqlTransaction或TransactionScope的事务是否会回滚?

时间:2015-04-14 15:53:39

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

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

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

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或其他地方找到任何信息,这些信息表明在这两种情况下的结果。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

如果我们正在谈论突然终止进程,那么"回滚"逻辑有机会运行,没有消息发送到服务器。这与一般异常处理不同,其中finally块通常会确保发生回滚。

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