【问题标题】:Does SQL server automatically rollback the changes on connection lost?SQL Server 是否会在连接丢失时自动回滚更改?
【发布时间】:2013-07-15 13:22:33
【问题描述】:

我有一个 sql server (server1) 和 webservice server (server2)。 server2 具有以下代码。从客户端获取结果请求并更新数据库。

 try
        {
            AppLogger.DebugFormat("Entered into save result - [{0}]", result.ID);
            int retry = 0;
            while (++retry <= 5)
            {
                try
                {
                    using (var oConnection = new SqlConnection("Connection string"))
                    {
                        oConnection.Open();
                        AppLogger.Debug("Saving data into db");
                        oConnection.Execute("storedproc1", new
                        {
                            param1 = Convert.ToInt32(result.value1),
                            param2 = Convert.ToInt32(result.value2),
                            param3 = result.value3=="Success",
                            param4 = result.vaue4
                        }, commandType: CommandType.StoredProcedure); 
                        AppLogger.DebugFormat("Save done with [{0}] try", retry);
                        break;
                    }
                }
                catch (SqlException sx)
                {
                    if (retry == 5)
                    {
                        AppLogger.Debug("sql exception occured");
                        throw;
                    }
                    else
                    {
                        AppLogger.ErrorFormat("Exception occurred [{0}] time(s), going to retry again after a minute", sx, retry);
                        System.Threading.Thread.Sleep(1000 * 60);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            AppLogger.Error("Unable to save result", ex);
            throw;
        }

webservice 服务器 (Server2) 碰巧遇到蓝屏错误并死机。我们重新启动它并从应用程序中找到以下日志信息。

 10:32:41.046 Entered into save result - 100023
 10:32:41.062 Saving data into db
 10:32:41.062 Save done with 0 try

 10:32:45.233 Entered into save result - 100024
 10:32:41.248 Saving data into db
 10:32:41.248 Save done with 0 try

但是 sql server (server1) 没有这个更新。

下面是我的存储过程

Alter Procedure storedproc1
@Param1 int,
@Param2 int,
@Param4 varchar(2000),
@Param3 bit
AS
SET NOCOUNT ON

BEGIN   
     Declare @param5 varchar(30)
     select @param5=col1 from table1 where col2=@param1 and col3=@param2
     UPDATE table1 set col4=@param3, col5=@param4 where col2=@param1 and col3=@param2

     IF not exists (select 1 from table1 where col1 = @param5 and col5 is null and col4 is null)
     BEGIN
        UPDATE table2 set col2='statuschange'
        where col1 in (select distinct col6 from table1 where col1=@param5)
     END
END  

有人能告诉我为什么应用程序服务器说保存完成而 sql 服务器没有更新吗?

sql server 是否在连接丢失时回滚更改?

顺便说一句,我使用 dapper 与我的数据库通信。 Log4net 常用日志记录。

感谢您的宝贵时间, 埃森

【问题讨论】:

    标签: .net sql-server webserver


    【解决方案1】:

    一般来说,如果在连接丢失时有一个事务是打开的,那么该事务将被完全回滚。另一方面,如果事务已提交,其更改将在提交后立即发生服务器崩溃。

    您的代码未显示任何事务处理。如果在没有显式事务的情况下执行 SQL 代码,则每条语句都会在其自己的自动事务中运行。所以每一个完成的语句都会被保留。

    您看到的行为表明事务正在使用且未正确清理。这与事务池一起可能导致意外行为。

    跟踪此问题的一种方法是在 using(var oConnection) 块的开头执行 SELECT @@TRANCOUNT;。如果它的回报率高于预期,那么你就有问题了。它要么需要始终为0,要么如果 dapper 设置为在事务内部执行代码,则它需要始终为1。任何大于“默认”的值都指向事务泄漏。

    【讨论】:

    • 谢谢@Sebastian Meine,这种情况并不常见。它在过去六个月中发生过一次。 Transcount 为 0,我想这并不意味着发生此问题时它为 0。您的解释使我研究了该数据库处理的其他过程和查询。一些存储过程确实对这个表使用了事务。这些存储过程也有 100% 可能同时被执行。我正在清理交易混乱。由于我无法重现此问题。我想清理工作将在未来有所帮助。谢谢。
    • 删除事务时要小心。将代码包装在事务中可能有充分的理由。 (想想将资金从一个帐户转移到另一个帐户的典型示例。)但是,您可能希望研究统一它们的处理方式。您要么希望在程序内部而不在应用程序层中进行事务管理,要么在应用程序层而不在程序中进行事务管理。并且 - 回顾您最初的问题 - 确保它们始终关闭(提交或回滚),无论它们是如何打开的并且独立于潜在的错误情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2015-11-21
    • 2022-01-20
    • 2010-10-31
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多