SQL连接问题
本文关键字:问题 连接 SQL | 更新日期: 2023-09-27 18:06:47
我们有一个助手类,用来调用SQL Server上的存储进程。辅助函数如下所示:
using (sqlCon = new SqlConnection(connectionString))
{
// Create database command object
sqlCmd = sqlCon.CreateCommand();
sqlCmd.CommandTimeout = commandTimeout;
// Set command text AND command type
sqlCmd.CommandText = procedureName;
sqlCmd.CommandType = CommandType.StoredProcedure;
// Set command parameters
if (paramCollection != null)
{
foreach (DatabaseParameter dbParam in paramCollection)
{
SqlParameter sqlParam = sqlCmd.Parameters.Add(dbParam.ParameterName, dbParam.ParameterType);
sqlParam.Direction = dbParam.ParameterDirection;
sqlParam.Value = dbParam.ParameterValue;
if (dbParam.ParameterSize != -1)
sqlParam.Size = dbParam.ParameterSize;
if (dbParam.ParamPrecision != -1)
sqlParam.Precision = (byte)dbParam.ParamPrecision;
if (dbParam.ParamScale != -1)
sqlParam.Scale = (byte)dbParam.ParamScale;
}
}
try
{
sqlCon.Open();
}
catch
{
SqlConnection.ClearAllPools();
sqlCon.Open();
}
// Prepare command
sqlCmd.Prepare();
// Execute the statement
sqlCmd.ExecuteNonQuery();
if (sqlCmd.Parameters.Contains("@Result"))
return sqlCmd.Parameters["@Result"].Value;
else
return "Completed";
}
所以我们要确保连接是正确关闭的。该应用程序是一个多线程服务,所有线程都会定期调用这个方法。我们在调用上述helper方法的代码周围锁定(thisobject){}节,以防止线程窃取彼此的连接。
连接。Open是在一个try catch中使用ClearAllpools来清除断开的连接。
然而,我们在一天中断断续续地以随机间隔得到以下错误列表。
连接的当前状态正在连接。
或
连接的当前状态为打开。
这些错误大约每几千次调用一次代码,所以很难排除故障。有人看到类似的情况吗或者有什么想法吗?
我在处理多线程应用程序时遇到过这些类型的错误,即使使用lock
。经过无数个小时的调试,我从未发现问题,最终在放弃之前尝试了几次重新连接。到目前为止,我还没有看到这个错误再次出现。
int retries = 5;
while( true )
{
try
{
DbCommand cmd = GetCommand( sql );
using( DbConnection conn = cmd.Connection )
{
conn.Open();
// do stuff
break;
}
}
catch
{
Thread.Sleep( 1000 );
if( retries-- <= 0 )
{
throw;
}
}
}
嗯,我不能确定为什么连接失败。但是错的是是你的catch
块。你忽略了实际的错误,而用一个没有帮助的错误(你正在看到的错误)来代替它。
永远不要忽略异常。抛出它们是有原因的,并且往往包含有关系统遇到的意外错误的有用信息。你很难解决问题,因为你不看就把有用的信息扔掉了。
你看到的错误是来自你的catch
块的代码。这段代码实际上是在尝试做刚刚失败的事情,但方式略有不同。您需要记录您的错误,以便您可以首先找出它失败并到达catch
块的原因。
try/catch
块来说,一个好的经验法则是,只有当你准备处理异常时,你才应该捕获异常。这里你根本没有处理它,所以除非你这样做,否则你应该完全删除try/catch
。让异常冒泡到可以处理的地方。或者,用一些错误记录替换catch
块中的代码,并以一种有用且有意义的方式退出代码块(将错误返回给调用代码块,抛出带有捕获异常的自定义异常,等等)。
撇开其他不谈,您是否尝试过根据连接的State
有条件地进行操作?
using (sqlCon = new SqlConnection(connectionString))
{
if (sqlCon.State == ConnectionState.Open)
{
....
}
}