SqlTransaction错误导致应用程序崩溃
本文关键字:应用程序 崩溃 错误 SqlTransaction | 更新日期: 2023-09-27 18:18:08
这里有一些背景:我们的网站会周期性地崩溃,以至于不得不重新启动IIS;这几乎总是在给DLL打补丁后的一个小时内发生(我们使用的是Web Site项目,而不是Web Application项目,所以每个ASPX页面都是一个单独的DLL)。
在做一些研究,我发现,我们的自制DAL可以,而调试,导致内置的web服务器与Visual Studio实际上停止工作,并关闭,如果它遇到存储过程中的SQL错误(我的意思是,它不仅会抛出一个异常,显示在浏览器中,它实际上会说,web服务器已经经历了一个错误,需要关闭!)
进一步挖掘,错误似乎与在DAL中使用事务有关(包括Select语句)。似乎是这样的:
- 尝试执行存储过程,由于缺少/无效列或其他错误,存储过程失败。
- 应用程序代码捕获错误并重新抛出它(糟糕,是的,但我没有写这个)。
- 事务尝试提交尽管有异常,获得
transaction.Commit()
行上的NullReferenceException
(似乎是在Connection
属性上,因为有一个事务对象)。此外,这个NullRef似乎不能被捕获(我尝试了一个演示,强制崩溃与无效的Sproc和NullRef从未被捕获,即使输出错误给它的类型为System.NullReferenceException
) - 事务抛出错误,表示"事务已完成,不再可用"。
- ? ?但是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块,事务仍然尝试提交,这似乎会导致挂起。
如果在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)
{
}
}