【问题标题】:SqlTransaction causing application crash on error?SqlTransaction 错误导致应用程序崩溃?
【发布时间】:2011-12-16 14:49:59
【问题描述】:

这里有一些背景:我们的网站会定期崩溃到不得不重新启动 IIS 的程度;这几乎总是在修补 DLL 的一个小时内发生(我们使用的是网站项目,而不是 Web 应用程序项目,因此每个 ASPX 页面都是一个单独的 DLL)。

在进行一些研究时,我发现我们的自制 DAL 在调试时会导致带有 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 本身非常脆弱,具体用于数百个文件,因此我无法正确地从头开始重写。

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

    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 trans;那么您必须将该事务分配给 SqlCommand 对象 sqlComm.Transaction = trans 类似的东西..根据上面“缺少列”中的错误描述检查存储过程并确保您的 Select 语句、更新、删除 .. 是收到确切的参数,希望你没有这样做,当你只需要几个字段而不是很多时选择 *'s .. 需要查看代码和查询

标签: c# asp.net visual-studio-2008-sp1 sqltransaction


【解决方案1】:

如果您将事务代码包装在 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)
  {
  }
}

【讨论】:

猜你喜欢
  • 2020-10-06
  • 1970-01-01
  • 2017-08-22
  • 1970-01-01
  • 2015-10-21
  • 2016-06-04
  • 2011-08-24
  • 2014-05-03
  • 1970-01-01
相关资源
最近更新 更多