同时调用SQL Server多个并且连接相同

时间:2014-12-30 10:23:28

标签: c# web-services sql-server-2008

我创建了全局静态类,它有一个SqlConnection,如下面的代码所示:

public class Globals
{
    public static SqlConnection SqlDbConn;

    public static OpenConnection(String ConnString)
    {
        SqlDbConn = new SqlConnection(ConnString);
        SqlDbConn.Open();              
    }
}

然后创建了Web服务,它有更多功能。

我的问题是:如何在同一时间内在所有功能中使用相同的连接(SqlDbConn)?换句话说,有多用户同时调用这个Web服务,并且Web服务中的每个函数使用相同的SqlDbConn,这是真的吗?如果不是为什么?

最后,在Web服务中,我使用此构造函数初始化连接:

public class Service1 : System.Web.Services.WebService
{
    private static bool Initialized = false;

    static string ConnString= @"Data Source=192.168.1.1\SQLEXPRESS;UID=sa;PWD=0000;Initial Catalog=DBName; MultipleActiveResultSets=true";

    public Service1()
    {
        // This method called each function call
        if (!Initialized )
        {
            Globals.OpenConnection(ConnString);
            Initialized = true;
        }
    }
}

3 个答案:

答案 0 :(得分:3)

您应该在每次调用数据库时创建一个新的SqlConnection实例,并在完成后Dispose创建它。 SqlConnection有一个池化机制,可以为您创建和重用连接。处理单个连接对象上的每个调用都可能会在异步操作上抛出会话忙碌异常

答案 1 :(得分:2)

普遍接受的最佳实践,用于处理" raw"上的连接和命令。 ADO.NET级别总是尽可能地根据需要创建这些对象,并尽快再次释放它们。 ADO.NET已经内置了一个非常复杂的连接池机制 - 试图超越这个经过充分验证的机制毫无意义。

为了确保正确处理对象,通常也可以将它们放入using(...) { ... }块中 - 类似这样:

// define query as a string
string query = "SELECT ..... FROM ... WHERE ......";

// create connection and command in "using" blocks
using (SqlConnection conn = new SqlConnection(-your-connection-string-here-))
using (SqlCommand cmd = new SqlCommand(conn, query))
{
    // set up e.g. parameters for your SqlCommand

    // open the connection, execute the query, close the connnection again
    conn.Open();

    // for a SELECT, use ExecuteReader and handle the reader (or use SqlDataAdapter to fill a DataTable)
    // for UPDATE, INSERT, DELETE just use a ExecuteNonQuery() to run the command
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
           // handle the data from the reader
        }

        // close reader
        rdr.Close();
    }

    conn.Close();
}

答案 2 :(得分:0)

在线程存在的情况下,您的代码可能非常错误,并且在任何情况下,它都是Connection Pooling基础架构的糟糕副本,它已经在以有效的方式重用物理连接。

但是,您不需要进行多项更改才能获得更好的方法

public class Globals
{
    // Keep global just the connection string 
    // (albeit you could simply pass it every time)
    public static string ConnString {get;set;};

    // Change the OpenConnection method to return the SqlConnection created 
    public static SqlConnection OpenConnection()
    {
        SqlConnection cnn = new SqlConnection(ConnString);
        cnn.Open();              
        return cnn;
    }
}

.....

public class Service1 : System.Web.Services.WebService
{
    private static bool Initialized = false;
    public Service1()
    {
        // This method called each function call
        if (!Initialized )
        {
            // Don't hard code the connectionstring details, read it from CONFIG
            // See ConfigurationManager class....
            string connectionString = ReadConnectionStringFromYourConfigFile()
            Globals.ConnString = connectionString;
            Initialized = true;
        }
    }

    // An usage example of your Globals
    public int GetDatabaseValue()
    {
         using(SqlConnection cn = Globals.OpenConnection())
         {
            .....
         } // Here the connection will be closed and disposed also in case of exceptions...
    }
}