多用户连接并同时进行CRUD

时间:2011-05-09 08:47:09

标签: c# asp.net sql sql-server-2008 iis-7

我正在使用ASP.NET Framework 4,IIS 7和SQL Server 2008 R2。

我有一个错误: {column} not found in selected DataSource, SQL Reader is close,....

只有在以下情况下才会发生:

  1. 已连接多个用户。
  2. 他们同时进行CRUD(创建,回复,更新,删除)调用。
  3. 奇怪的是,它逃脱了我的追捕:

    try{
        Connexion_D.GetConnected();
        // doing CRUD
    }
    catch{
        // catching Error, avoid yellow page aspx
    }
    finally
    {
        Connexion_D.CloseConnection();
    } 
    

    我的连接类:

    public class Connexion_D
    {
    
        static public SqlConnection conn;
        static public SqlConnection GetConnected()
        {
            try
            {
                String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
                conn = new SqlConnection(strConnectionString);
            }
            catch (Exception excThrown)
            {
                conn = null;
                throw new Exception(excThrown.InnerException.Message, excThrown);
            }
    
            // Ouverture et restitution de la connexion en cours
            if (conn.State == ConnectionState.Closed) conn.Open();
            return conn;
        }
        static public Boolean IsConnected
        {
            get { return (conn != null) && (conn.State != ConnectionState.Closed) && (conn.State != ConnectionState.Broken); }
        }
    
        static public void CloseConnection()
        {
            // Libération de la connexion si elle existe
            if (IsConnected) conn.Close();
        }
    }
    

    所以我认为代码不对/有错误。

    我认为它可能是IIS和SQL服务器的配置。

    有什么想法吗?

    提前完成。

1 个答案:

答案 0 :(得分:4)

如果我理解你正确做了什么,那么这看起来非常可疑:

static public SqlConnection conn;     
static public SqlConnection GetConnected() {         
    try         
    {             
        String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;             
        conn = new SqlConnection(strConnectionString);
    } 
}

static public void CloseConnection() {           
    // Libération de la connexion si elle existe           
    if (IsConnected) conn.Close();       
}   

您正在使用静态连接变量,这意味着当您关闭它时,您将关闭最后一个已打开的连接变量。

在多用户场景中,您可能会遇到这种情况:

  • 用户A:创建连接(并返回连接1)
  • 用户A:执行查询(针对连接1运行)
  • 用户B:创建连接(并返回连接2)
  • 用户A:关闭连接(最后一次打开是2,因此关闭)
  • 用户B:执行查询(针对连接2运行,已经关闭...砰)

顺便说一下,您应该重新考虑将您的连接作为公共成员变量:

static public SqlConnection conn;     

这通常被认为是不好的做法,如果你班级以外的任何代码开始搞乱它的内部变量,可能导致意外/难以追踪错误。

编辑:

最明显的解决方案似乎是阻止连接变为静态。您的客户端代码可能看起来像这样:

try{
    // use using block around connection, calls dispose automatically when
    // block ends...
    using(var connectionWrapper = new Connexion_D()) {
        var connectedConnection = connectionWrapper.GetConnected();        
        // do CRUD
    }
}
catch{
    // catching Error, avoid yellow page aspx
    // Really you should probably be doing something with the exception (logging?)
    // particularly since you go to the effort of throwing it from your Connection_D
    // class.
}

您的班级代码如下:

/* Implement IDisposable to cleanup connection */
public class Connexion_D : IDisposable 
{
    public SqlConnection conn;

    public SqlConnection GetConnected()
    {
        try
        {
            String strConnectionString = ConfigurationManager.ConnectionStrings["xxxxx"].ConnectionString;
            conn = new SqlConnection(strConnectionString);
        }
        catch (Exception excThrown)
        {
            conn = null;
            throw new Exception(excThrown.InnerException.Message, excThrown);
        }

        // Ouverture et restitution de la connexion en cours
        if (conn.State == ConnectionState.Closed) conn.Open();
        return conn;
    }
    public Boolean IsConnected
    {
        get { return (conn != null) && (conn.State != ConnectionState.Closed) && (conn.State != ConnectionState.Broken); }
    }

    public void CloseConnection()
    {
        // Libération de la connexion si elle existe
        if (IsConnected) { 
            conn.Close();
            conn = null;
        }
    }

    // Implement IDisposable.
    // Do not make this method virtual.
    // A derived class should not be able to override this method.
    public void Dispose()
    {
        // Close connection
    }
}

有关实施IDisposable的更多信息,请参阅this