2012-08-28 42 views
1

我有用C#編寫的命令行實用程序,它更新數據庫中的一些記錄,然後進入循環檢查一些其他的東西。出於某種原因,執行SQL後,SQL執行始終會在SQL Server 2008中保留一個正在等待的睡眠命令會話。我可以使用SQL Server活動監視器並運行sp_who2來確認。但是,SQL事務已經成功實現。我可以通過代碼中的調試以及數據庫中數據記錄的時間戳來說明這一點。 此外,當我明確停止命令行實用程序時,打開的睡眠會話將被終止。這似乎表明我的函數創建了一些SQL連接對象,直到它在應用程序中止時由CLR進行垃圾回收時才能處理。這怎麼會發生?謝謝。以下是代碼:ExecuteNonQuery離開睡眠等待命令會話

bool result = false; 
    using (SqlConnection conn = new SqlConnection(this.Connection)) 
    { 

     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      cmd.CommandText = 
       @"if not exists (select id from pl where [email protected] and [email protected] and dateInactivated is null) 
         insert into pl(sj,ej,pf, br, tk, lastModified) 
         values(@sj,@ej,@pf,@br,@tk,getDate()) 
        else 
         update pl set [email protected],[email protected],[email protected],[email protected],[email protected],lastModified=getDate() 
         where [email protected] and [email protected] and dateInactivated is null 
        "; 

      cmd.Parameters.AddWithValue("@sj", sj); 
      cmd.Parameters.AddWithValue("@ej", ej); 
      cmd.Parameters.AddWithValue("@pf", pf); 
      cmd.Parameters.AddWithValue("@br", br); 
      cmd.Parameters.AddWithValue("@tk", tkData); 
      cmd.CommandTimeout = 60; 
      SqlTransaction trans = null; 
      try 
      { 
       conn.Open(); 
       trans = conn.BeginTransaction(); 
       cmd.Transaction = trans; 
       cmd.ExecuteNonQuery(); 
       trans.Commit(); 
       conn.Close(); 
       result = true; 
      } 
      catch (SqlException ex) 
      { 
       if (trans != null) 
       { 
       trans.Rollback(); 
       } 
       Log.WriteLog(LogLevel.ERROR, ex.Message); 
       result = false; 
      } 
      finally 
      { 
       if (conn.State != ConnectionState.Closed) 
       { 
       conn.Close(); 
       } 
      } 
     } 

    } 

    return result; 

請注意,tk字段是一個xml數據庫字段。

回答

6

這叫做連接池,和you want it to work this way

基本上,完全刪除連接然後爲您的應用程序重新建立連接比僅僅重新使用先前調用代碼時留下的空閒連接承受更高的懲罰。這是一件好事。

+0

我想過連接池。但我的理解是,它實際上只是託管堆中的一些緩存對象。謝謝(你的)信息。很高興知道。 – Tuzki

+0

它只是託管堆中的一些緩存對象,它們將非託管句柄保存到連接中。 –

2

這是由於池。 99.99%的時間,這是一件好事 - 它減少了連接的數量,並且如果多線程使得更少的連接同時打開的話。

如果將Pooling=false添加到連接字符串中,將不會使用它。現在唯一的理由這樣做是:

  1. 作爲一項臨時措施,如果你的某個地方漏池連接 - 注意,這使情況變得更糟至於性能也越高,但它不會碰到最大游泳池大小。這裏重點介紹臨時
  2. 您有客戶端應用程序共享一個數據庫,並使用連接的時間很短。在這裏你想關閉池,因爲雖然它使每個客戶端效率較低,但它減少了服務器本身的壓力。

第二個是非常罕見的。首先應該是非常罕見的 - 再次強調臨時

+0

感謝您的詳細信息。 – Tuzki