SQL连接问题

时间:2011-08-28 17:45:46

标签: c# sql-server connection

我们有一个帮助器类,用于在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";
        }

因此我们确保正确关闭连接。 该应用程序是一个多线程服务,所有线程都经常调用此方法。我们围绕调用上述帮助方法的代码锁定(thisobject){}部分,以防止线程窃取彼此的连接。

connection.Open位于带有ClearAllpools的try catch中,用于清除断开的连接。

但是,我们间歇性地在一天中随机获取以下错误列表。

  

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

  

连接的当前状态已打开。

错误发生在代码调用的每几千次中,因此很难排除故障。有没有人在可能出错的地方看到任何类似或想法?

3 个答案:

答案 0 :(得分:1)

嗯,我不能确定连接失败的原因。但是错误的是你的catch块。你忽略了实际的错误并用一个无用的错误(你正在看到的那个)替换它。

从不忽略异常。它们被抛出是有原因的,并且往往包含有关系统遇到的意外错误的有用信息。你在找出问题时遇到了麻烦,因为你在没有看到它的情况下扔掉了那些有用的信息。

您看到的错误来自catch块中的代码。这段代码本质上是试图做出失败的确切事情,但方式略有不同。您需要记录错误,以便找出失败的原因并首先到达catch块。

try/catch块的一个好的经验法则是,如果你准备处理异常,你应该只捕获异常。在这里你根本不处理它,所以除非你这样做,否则你应该完全删除try/catch。让异常泡到某个可以处理的地方。或者,将catch块中的代码替换为一些错误记录,并以有用且有意义的方式退出代码块(将错误返回到调用代码块,抛出自定义异常,其中包含捕获的异常,等)。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

除此之外,您是否尝试过根据连接的State有条件地进行处理?

using (sqlCon = new SqlConnection(connectionString))
{
    if (sqlCon.State == ConnectionState.Open)
    {
        ....
    }
}