乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      ASP.NET與數(shù)據庫連接池

       悟靜 2012-06-14
      99人閱讀 評論(0) 收藏 舉報

      防止可淹沒應用程序的池溢出

      大多數(shù) ADO.NET 數(shù)據提供程序使用連接池,以提高圍繞 Microsoft 斷開連接的 .NET 結構構建的應用程序的性能。應用程序首先打開一個連接(或從連接池獲得一個連接句柄),接著運行一個或多個查詢,然后處理行集,最后將連接釋放回連接池。如果沒有連接池,這些應用程序將花費許多額外時間來打開和關閉連接。

      當您使用 ADO.NET 連接池來管理基于 Web 的應用程序和客戶端/服務器 Web 服務應用程序的連接時,您的客戶通常會獲得更快的連接和更好的總體性能。但是,當您的應用程序或 Web 站點上突然涌入了同時希望進行連接的大量客戶時,會發(fā)生什么事情呢?您的應用程序會沉沒,還是會游泳?就像救生員一樣,您需要仔細監(jiān)視連接池,以維護它的良好性能,并防止連接池發(fā)生溢出。我們首先探討連接池可能溢出的原因,然后討論如何編寫代碼或使用 Windows 性能監(jiān)視器來監(jiān)視連接池。

      正如我于 2003 5 月發(fā)表的 Swimming in the .NET Connection Pool (InstantDoc ID 38356) 一文中討論的那樣,當您使用連接池時,您需要知道許多有關可伸縮性和性能的詳細信息。請記住,您需要監(jiān)視和管理兩個基本因素:每個池管理的連接數(shù)和連接池的數(shù)量。在一個有效的生產系統(tǒng)中,池的數(shù)量通常很少(1 10),而且,使用中的連接的總數(shù)也很少(少于 12 )有效的查詢只用不到一秒鐘的時間就可以完成,并斷開連接。因此,即使有數(shù)百個客戶同時訪問您的 Web 站點,相對較少的幾個連接常常足以處理整個負載。為了使您的應用程序有效地運行,您必須使連接資源處于自己的控制之下,并要監(jiān)視池的狀態(tài),這樣,在監(jiān)視池發(fā)生溢出以及您的客戶開始抱怨(或離開您的網站)之前您會收到某種警告。

      為什么會發(fā)生連接池溢出?

      參加電子郵件討論組的人常常抱怨應用程序是如何在測試中是而在形成為產品時就變成了的。有時,他們會報告說,當連接了大約 100 個客戶端時,應用程序會停止或掛起。請記住,一個池中的默認連接數(shù)是 100。如果您嘗試從池中打開 100 個以上的連接,ADO.NET 會使應用程序的連接請求排隊等候,直到有空閑的連接。應用程序(及其用戶)將這種情況視為進入 Web 頁的延遲或視為應用程序死鎖。讓我們首先討論一下這個問題是如何產生的。

      ADO.NET 中,SqlClient .NET 數(shù)據提供程序為您提供了兩種打開和管理連接的方法。首先,當您需要手工管理連接時,可以使用 DataReader 對象。利用這種方法,您的代碼將構造一個 SqlConnection 對象,設置 ConnectionString 屬性,然后使用 Open 方法來打開連接。當代碼完成 DataReader 后,您要在 SqlConnection 對象停止作用之前關閉 SqlConnection。要處理行集,您可以將 DataReader 傳遞到應用程序中的另一個例程,但仍然需要確保 DataReader 及其連接處于關閉狀態(tài)。如果您不關閉 SqlConnection,代碼會泄漏每個操作的連接,于是連接池對連接進行累積,最后便發(fā)生溢出。與 ADO Visual Basic (VB) 6.0 中的情況不同,.NET ***回收器不會為您關閉 SqlConnection 并進行清理。我稍后要討論的 清單 1 顯示了如何打開連接和生成 DataReader 以從一個簡單的查詢返回行集,來向連接池施加壓力的。

      您也可能在使用 DataAdapter 對象時遇到問題。DataAdapter Fill Update 方法可自動打開

       

       

      用不到五個連接來處理每天的幾十萬次點擊。

      標注 A 中的例程創(chuàng)建 SqlConnection 對象和 SqlCommand 對象,設置 CommandText,并打開連接。然后,標注 B 中的代碼確定執(zhí)行 DataReader 時是否使用 CommandBehavior.CloseConnection,這取決于用戶在 Web 窗體上選擇了哪些 CheckBox 控件。

      在標注 C 的代碼中,我指定是否將 DataReader 行集綁定到 DataGrid,或者是否在整個行集中進行循環(huán)。標注 C 的代碼測試當您到達通過 DataReader 從數(shù)據提供程序傳遞回來的行集的末尾時會發(fā)生什么事情。

      現(xiàn)在,我使用標注 D 中的代碼來指定是手工關閉連接還是讓某個其他操作(例如,數(shù)據綁定)來完成這項工作。坦白地說,以手工方式關閉連接通常是最安全的,因此,您可以肯定連接不會被孤立。

      如果代碼成功地運行到這一步,說明我已經成功地打開和關閉了 110 個連接。不過,如果出了問題,標注 E 的代碼中的異常處理程序會將異常(通常是 Timeout)作為 InvalidOperationException 捕獲,該異常是連接池已滿時 ADO.NET 的響應方式。

      1 匯總了各個選項使例程成功運行或失敗的方式。請注意,如果您不設置 CommandBehavior.CloseConnection 選項,您的操作最終會失敗即使在使用綁定控件的情況下也是如此。即使您使用該選項,但如果您沒有使用復雜的綁定控件,或者沒有手工關閉 SqlDataAdapter SqlConnection,該進程仍然會失敗。

      當我結束了這些示例應用程序的運行后,我已經生成了 1000 多個以上的池連接所有連接均處于孤立狀態(tài)。雖然“SQL Server 用戶連接計數(shù)為 0,但留下大約 40 個連接池。在我重新引導系統(tǒng)之前,孤立的池不會消失。

      我用于此測試的示例應用程序包括使用 DataAdapter 來返回行的例程。除非您手工管理連接,否則,DataAdapter 將正確地打開和關閉 SqlConnection 對象,因此,您不太可能遇到孤立的池連接。不過,如果您的應用程序同時使用 DataReader DataAdapter,您可能會發(fā)現(xiàn),如果某個連接與一個未關閉的 DataReader 相關聯(lián),則 DataAdapter 無法針對該連接運行查詢。

      確定連接池何時達到最大連接數(shù)

      正如我在 Swimming in the .NET Connection Pool 一文中討論的那樣,當連接池達到您通過 Max Pool Size ConnectionString 選項指定的最大連接數(shù)時,ADO.NET 將阻止任何隨后打開額外連接的嘗試。如果某個連接在您在 ConnectionTimeout 選項中指定的時間之前變?yōu)榭捎茫?SPAN lang=EN-US>.NET 數(shù)據提供程序將向您的應用程序傳遞一個指向該連接的指針,以便將控件返回給應用程序。不過,如果沒有及時釋放任何連接,連接請求將引發(fā) InvalidOperationException 異常。

      現(xiàn)在您必須決定要采取的措施,我不建議您告訴用戶您已經用完了所有連接。有些應用程序會通知用戶系統(tǒng)正忙于幫助其他客戶,并建議用戶稍后進行訪問。其他應用程序則播放一段動畫,通知用戶系統(tǒng)尚未死鎖,而是正在忙于處理他們的請求。同時,您的代碼重新嘗試操作。在所有情況下,您應該

      記錄這些故障,以便幫助診斷問題的癥結所在,并記錄您已經耗盡了資源。

      監(jiān)視連接池

      您已經打開和關閉了一個連接,現(xiàn)在您希望知道該連接是否仍然處于打開狀態(tài)。您可以使用幾種方法來確定有多少連接仍然處于打開狀態(tài),以及它們正在執(zhí)行何種操作:

       

      運行 sp_who sp_who2。這些系統(tǒng)存儲過程從 sysprocess 系統(tǒng)表返回信息,該系統(tǒng)表顯示所有工作進程的狀態(tài)及其有關信息。通常,您會看到每個連接有一個服務器進程 ID (SPID)。如果您是通過在連接字符串中使用 Application Name 參數(shù)來命名您的連接的,那么,您將很容易找到工作的連接。

      使用帶有 SQLProfiler TSQL_Replay 模板的 SQL Server 事件探查器來跟蹤打開的連接。如果您很熟悉事件探查器,此方法比通過使用 sp_who 進行輪詢要更容易。

       

      使用性能監(jiān)視器來監(jiān)視池和連接。我稍后再討論此方法。

      在代碼中監(jiān)視性能計數(shù)器。您可以通過使用例程來提取計數(shù)器或通過使用新的 .NET PerformanceCounter 控件來監(jiān)視連接池的狀況和已建立的連接的數(shù)量。這兩種方法都包括在您可以從 http://www. 進行下載的示例應用程序中。

      現(xiàn)在我們將討論如何查找連接池計數(shù)器,以及如何使用這些監(jiān)視方法。

      連接池計數(shù)器在哪里?要監(jiān)視連接池計數(shù)器,您必須監(jiān)視 ADO.NET 在其中創(chuàng)建和增加這些計數(shù)器的系統(tǒng)。如果您從遠程系統(tǒng)進行連接,ADO.NET 并不總是在 Microsoft IIS 服務器或 SQL Server 上創(chuàng)建池;它在 ADO.NET 代碼運行的系統(tǒng)上創(chuàng)建池。此系統(tǒng)可以是運行 IIS、Web 應用程序或 Web 服務的遠程 Windows 或中間層系統(tǒng)。相反,SQL Server 性能計數(shù)器位于 SQL Server 系統(tǒng)上而不是客戶端上。

      使用性能監(jiān)視器來監(jiān)視池。如果您使用 Microsoft 管理控制臺 (MMC) Windows 2000 系統(tǒng)監(jiān)視器管理單元,則您可以通過從 Performance 對象下拉列表中選擇 .NET CLR Data 來用圖形表示 SqlClient 計數(shù)器,如 1所示。請注意,您可以通過選擇 _global_ 計數(shù)器實例來監(jiān)視所有進程,或者,您可以查看某個特定實例每個池生成自己的一組監(jiān)視器。性能監(jiān)視器可列出這些計數(shù)器,并將它們作為所選定的性能對象的實例提供。但性能監(jiān)視器不會公開這些計數(shù)器,除非有實例需要它們進行監(jiān)視。例如,圖 1 顯示了 .NET CLR Data 性能對象,但沒有列出特定實例。這意味著您必須至少創(chuàng)建一個連接,以便使 _global_ 實例連同每個進程的特定實例一起出現(xiàn)。這種行為對于您的代碼來說是個問題;您將無法使用 PerformanceCounter 控件來返回其中的任何計數(shù)器,直到 ADO.NET 在打開連接時創(chuàng)建這些計數(shù)器。所以說,這個規(guī)定真有點令人左右為難。當您使用此方法時,因為缺少有效計數(shù)器實例,所以會引發(fā)異常此時要準備好捕獲異常。

      您還可以通過使用 SQL Server 性能計數(shù)器 User Connections 來監(jiān)視打開的連接的數(shù)量。該計數(shù)器被列在 Performance 對象下拉列表中的 SQL Server: General Statistics 下。我喜歡監(jiān)視 User Connections 值和一些所選定的 .NET CLR Data SqlClient 計數(shù)器(我稍后將討論此內容),因為我可以獲得我需要的信息,而不必擔心實例。

      使用代碼來監(jiān)視性能計數(shù)器。當您需要以編程方式監(jiān)視連接池時,您可以編寫代碼來監(jiān)視由 SqlClient 管理的性能計數(shù)器這些計數(shù)器與 MMC Windows NT 性能監(jiān)視器管理單元所提供的計數(shù)器是相同的。編寫執(zhí)行監(jiān)視的代碼似乎是一件有些令人畏懼的事情。但我已經提供了從 SqlClient 提供程序的內部工作提取這些計數(shù)器的例程的快照(作為本文提供的可下載程序之一)。

      您可以編寫檢查 2顯示的五個計數(shù)器的代碼。通過利用這五個計數(shù)器,您可以實時監(jiān)視連接池。.NET 預期您會在性能監(jiān)視器中提供一個類別復制的 Performance Object并從那些注冊到系統(tǒng)的計數(shù)器中選擇適當?shù)挠嫈?shù)器。要訪問 SqlClient 計數(shù)器,請將該類別設置為 .NET CLR Data

      使用 PerformanceCounter 控件。您可能會發(fā)現(xiàn),在設計時向您的應用程序窗體添加 PerformanceCounter 要比手工編寫代碼來訪問性能計數(shù)器更加容易。要使用 PerformanceCounter 控件,請從“Visual Studio .NET 工具箱組件菜單中選擇一個 PerformanceCounter,將它拖到您的應用程序窗體,然后設置屬性,如 2 所示。這些控件工作在 Web 窗體和 WinForms 應用程序中。

      因為 PerformanceCounter 控件提供了方便的下拉列表,所以,您可以在設計時看到任何一種性能計數(shù)器類別、計數(shù)器名稱和特定實例您將要運行的實例除外。這意味著您必須使用圖 2 顯示的方法來捕獲應用程序正在使用的池的適當實例。為了回避這個問題,我選擇 _global_ 實例。再次說明一下,此方法假設某個應用程序已經至少創(chuàng)建了一個池,因此您需要做好不存在計數(shù)器實例時 ADO.NET 引發(fā)異常的準備,就像它在不存在池連接時也會引發(fā)異常一樣。

      注意不準確的池計數(shù)。因為 SqlClient .NET 數(shù)據提供程序中存在 .NET 框架 1.1 尚未解決的錯誤,所以,性能計數(shù)器會在池實際上已經刪除時錯誤地指示池仍然存在。我能通過結束 MMC 性能監(jiān)視器管理單元、然后結束 Visual Studio .NET 來驗證池已經不再存在。這些步驟說明,.NET 數(shù)據提供程序在創(chuàng)建連接池的進程結束時會正確地刪除連接池。顯然,這種不準確性降低了性能計數(shù)器在監(jiān)視池方面的有效性,所以我希望 Microsoft 將來能解決這個問題。

      計數(shù)器不顯示的內容

      您可能會面臨的一個問題是無法從計數(shù)器或 SqlClient 屬性看到每個池的配置。每個 SqlConnection 對象的 ConnectionString 保存著這些池設置的密鑰。因為您不能依賴于默認設置,所以很難確定池幾乎已滿或很難使用。這會成為未來版本的 ADO.NET 的另一個方便功能。

      不過,假設您知道各個連接池 ConnectionString 參數(shù)的值,則利用清單 1 中的代碼,您可以很容易地設置一個計時器來檢查您創(chuàng)建的特定池并報告使用百分比。然后,監(jiān)視應用程序會向您發(fā)出警報,以便您可以解決問題并防止溢出。

      最后,請記住,ADO.NET 采用的方法與基于 COM ADO 有所不同。Visual Basic .NET 完全改變了放棄對象的方式,并且不再確保 Connection 對象在停止作用時被關閉。請確保 SqlConnection 對象(或任何 Connection 對象)在停止作用之前被關閉。

      連接池是一種非常強大的功能,它可以提高應用程序的性能。但如果您不是一個出色的救生員,您的連接池會成為一個危害而不是一個優(yōu)點。我希望本文討論的方法有助于您有效地監(jiān)視連接池并滿足用戶的需要。

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多