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来清除断开的连接。

然而,我们在一天中断断续续地以随机间隔得到以下错误列表。

连接的当前状态正在连接。

连接的当前状态为打开。

这些错误大约每几千次调用一次代码,所以很难排除故障。有人看到类似的情况吗或者有什么想法吗?

SQL连接问题

我在处理多线程应用程序时遇到过这些类型的错误,即使使用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)
    {
        ....
    }
}