【问题标题】:SqlCommand state closed when SqlConnection state is openSqlConnection 状态打开时 SqlCommand 状态关闭
【发布时间】:2015-05-14 01:50:31
【问题描述】:

我在 SqlDataRreader 类中遇到了间歇性问题,我打开了一个 SqlConnection 并且它的状态是 OPEN,但是当我使用 SqlConnection 创建一个 SqlCommand 时,SqlConnection' s 状态为CLOSED。这只发生在大约十分之一的尝试中,因此可能是时间问题。

请注意,我没有将连接放在 Using 块中,而是独立打开/关闭连接,因为我通常一次执行多个命令,但是问题通常发生在第一次在刚刚执行的连接上执行命令时已打开。

连接代码为:

    private SqlConnection sql;

    public Result Connect(string database)
    {
        string connection = Config.environments[Config.environment][database];
        try
        {
            // Create and open the connection
            sql = new SqlConnection(connection);
            sql.Open();

            if (sql == null || sql.State != System.Data.ConnectionState.Open)
                return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "]");
            return new Result(true, "Connect to Database", "Connected to database [" + connection + "]");
        }
        catch (Exception e)
        {
            return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "] " + e.ToString());
        }
    }

运行命令代码为:

    private DataTable RunSql(string statement)
    {
        if (sql == null || sql.State != System.Data.ConnectionState.Open)
            throw new ScriptException("Cannot execute SQL command, no database connection established [" + statement + "]");

        // Create and execute the SQL statement
        using (SqlCommand command = new SqlCommand(statement, sql))
        {
            command.CommandTimeout = Config.sqlTimeout;

            try
            {
                using (SqlDataReader reader = command.ExecuteReader()) // ERROR OCCURS HERE! - sql.State is OPEN, but command.State is CLOSED ???
                {
                    // Check is the reader has any rresults
                    if (reader.HasRows)
                    {
                        DataTable data = new DataTable();
                        data.Load(reader);
                        return data;
                    }
                    else
                    {
                        throw new Exception("No results found for statement: " + statement + ", on server: " + sql.DataSource + ", in database: " + sql.Database);
                    }
                }
            }
            catch (SqlException)
            {
                //Log things here
            }

            throw new ScriptException("Error executing sql command: " + statement);
        }
    }

重现问题的代码(偶尔):

    private DataTable RunSingleCommand(string database, string command)
    {
        Log(Connect(database));
        return RunSql(command);
    }

【问题讨论】:

  • 在运行命令之前,您永远无法确保连接已成功打开...
  • @Grant,这背后有什么原因吗?发生异常时 SqlConnection 是 OPEN 的,所以连接没有超时。
  • @Ignaus,检查if (sql == null || sql.State != System.Data.ConnectionState.Open) 是否不足以验证连接是否打开?这在创建命令之前发生了两次。
  • @Scotty 如果您使用 statments .NET 将重新使用连接放回连接池。
  • 我敢打赌,您的问题是多个线程正在调用这些方法 - 所以会发生一个线程已将新的 Connection 分配给您的 sql 变量。然后它Opens 它。然后它去使用它,在它成功之前,第二个线程将一个新的Connection 分配给你的sql 变量。现在,在第二个线程设法Open 它之前,您的第一个线程现在读取sql,获取关闭的连接,然后您会得到您所描述的症状。

标签: c# sql sql-server sqldatareader


【解决方案1】:

我可以建议的是在打开连接之前在 Connection 命令中,进行条件检查以了解连接当前是否打开。只有在关闭模式下才打开新连接

try
{
    // Create and open the connection
    sql = new SqlConnection(connection);

    if (sql.State != System.Data.ConnectionState.Open)
    {  
        sql.Open();
    }

    return new Result(true, "Connect to Database", "Connected to database [" + connection + "]"); 
}    
catch (Exception e) 
{
    return new Result(false, "Connect to Database", "Could not connect to database [" + connection + "] " + e.ToString());
}

【讨论】:

    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 2015-07-10
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多