以下是一些背景知识:我们的网站会定期崩溃,无法重新启动IIS;这几乎总是在修补DLL的一小时内发生(我们使用网站项目,而不是Web应用程序项目,因此每个ASPX页面都是一个单独的DLL)。
在进行一些研究时,我发现我们的自制DAL可以在调试时导致内置的Web服务器与Visual Studio实际停止工作并在存储过程中遇到SQL错误时关闭(我的意思是不仅会抛出浏览器中显示的异常,而且实际上会说Web服务器出现错误并需要关闭!)
在进一步挖掘时,错误似乎与DAL中所有事务(包括Select语句)的事务使用有关。似乎发生了这样的事情:
NullReferenceException
行上获得transaction.Commit()
(似乎在Connection
属性上,因为存在事务对象)。此NullRef似乎无法捕获(我尝试了一个强制崩溃与无效Sproc并且NullRef从未被捕获的演示,即使输出错误的类型为System.NullReferenceException
)现在,我不知道这是否是导致IIS崩溃的原因,但它似乎很可疑,并且在任何情况下都是一个明显的错误。
之前没有处理过交易并且只有它们的基本概念,我的第一个问题是为什么事务在抛出异常后仍然试图提交?我的第二个问题是如何修复失败的提交以及可能无限循环的异常,直到服务器死亡。添加这样的东西是不是有意义(该方法采用名为transaction
的SqlTransaction参数):
catch (SqlException se)
{
if (transaction != null)
{
transaction.Rollback();
}
throw;
}
这个小小的改动是否会修复我认为崩溃IIS的常量异常循环? DAL本身非常脆弱,具体使用在数百个文件中,所以我无法正确地重写它。
编辑整个代码块就是这样(遗留代码 - 使用旧的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块执行,那么事务仍然会尝试提交,这似乎导致了挂起。
答案 0 :(得分:0)
如果您将交易代码包装在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)
{
}
}