SqlTransaction错误导致应用程序崩溃

本文关键字:应用程序 崩溃 错误 SqlTransaction | 更新日期: 2023-09-27 18:18:08

这里有一些背景:我们的网站会周期性地崩溃,以至于不得不重新启动IIS;这几乎总是在给DLL打补丁后的一个小时内发生(我们使用的是Web Site项目,而不是Web Application项目,所以每个ASPX页面都是一个单独的DLL)。

在做一些研究,我发现,我们的自制DAL可以,而调试,导致内置的web服务器与Visual Studio实际上停止工作,并关闭,如果它遇到存储过程中的SQL错误(我的意思是,它不仅会抛出一个异常,显示在浏览器中,它实际上会说,web服务器已经经历了一个错误,需要关闭!)

进一步挖掘,错误似乎与在DAL中使用事务有关(包括Select语句)。似乎是这样的:

  1. 尝试执行存储过程,由于缺少/无效列或其他错误,存储过程失败。
  2. 应用程序代码捕获错误并重新抛出它(糟糕,是的,但我没有写这个)。
  3. 事务尝试提交尽管有异常,获得transaction.Commit()行上的NullReferenceException(似乎是在Connection属性上,因为有一个事务对象)。此外,这个NullRef似乎不能被捕获(我尝试了一个演示,强制崩溃与无效的Sproc和NullRef从未被捕获,即使输出错误给它的类型为System.NullReferenceException)
  4. 事务抛出错误,表示"事务已完成,不再可用"。
  5. ? ?但是VS web服务器崩溃了。调试这部分似乎挂在上面的异常,永远不会离开方法。

现在,我不知道这是否是导致IIS崩溃的原因,但它看起来很可疑,无论如何这都是一个明显的错误。

之前没有处理过事务,只有它们的基本概念,我的第一个问题是为什么在抛出异常后事务仍然试图提交?我的第二个问题是如何修复失败的提交和可能无限循环的异常,直到服务器死亡。添加这样的内容(该方法接受名为transaction的SqlTransaction参数)不是很有意义吗?

catch (SqlException se) 
{
    if (transaction != null)
    {
        transaction.Rollback();
    }
    throw;
}

这个小的改变会修复恒定的异常循环,我认为是崩溃的IIS?DAL本身非常脆弱,具体用于数百个文件中,因此我无法从头开始正确地重写它。

EDIT整个代码块是这样的(同样,遗留代码-使用旧的microsoft数据访问块助手):

    public static DataSet ExecuteDatasetStoredProc(SqlConnection conn, String storedProcName, SqlTransaction transaction, params SqlParameter[] storedProcParms)
    {
        try
        {
            // Execute the stored proc
            if (transaction != null)
            {
                return SqlHelper.ExecuteDataset(transaction, CommandType.StoredProcedure, storedProcName, storedProcParms);
            }
            else
            {
                return SqlHelper.ExecuteDataset(conn, CommandType.StoredProcedure, storedProcName, storedProcParms);
            }
        }
        catch (SqlException se)
        {
            throw new ApplicationException("Error calling " + storedProcName + ". " + se.Message, se);
        }
    }

但是,如果执行catch块,事务仍然尝试提交,这似乎会导致挂起。

SqlTransaction错误导致应用程序崩溃

如果在try catch中包装事务性代码

Try
{
// your code that you assign and execute the SQl
}
catch (SQLException sqlex)
{
  try 
  {
    //try to do the rollback here.. don't always assume the commit or rollback will work
  }
  catch (Your SQL Exception ex)
  {
  }
}