簡體   English   中英

在同一時間和同一連接上多次調用SQL Server

[英]Calling SQL Server more than one at same time and same connection

我創建了全局靜態類,它具有一個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;
        }
    }
}

您應該在對數據庫的每次調用上創建一個新的SqlConnection實例,並在完成DisposeDispose SqlConnection具有一種池化機制,可以為您創建和重用連接。 處理單個連接對象上的每個調用可能會在異步操作上引發會話繁忙的異常

通常,在“原始” 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();
}

您的代碼在存在線程的情況下可能是非常錯誤的,在任何情況下,它都是連接池基礎結構的較差副本,它已經負責有效地重用物理連接。

但是,您無需進行太多更改即可擁有更好的方法

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...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM