簡體   English   中英

找出 sql 服務器連接在 c# 中處於打開狀態的位置

[英]Find out where sql server connections are being left open in c#

我繼承了大量 C# dotnet 代碼,這些代碼顯然在某些地方沒有關閉與 sql 服務器的連接或其他東西,我得到了

The timeout period elapsed prior to obtaining a connection from the pool: This may have occurred because all pooled connections were in use and max pool size was reached

這種情況經常發生,通常同時發生,但我不知道有什么安排好的。 手動搜索代碼中的每一個小地方也是不可能的。 任何想法如何在不手動檢查代碼中的每一個 function 的情況下解決這個問題?

不想通過代碼 go 的問題在於它很可能不是單個實例或區域,並且可能取決於您在生產環境中獲得最多流量的位置。 您可以有一個看起來相當無害的查詢,可以通過.AsNoTracking()或更好的連接/包含來稍微改進,而不是優化不佳的單個大查詢。 也有整個設計存在缺陷的情況(我曾經進入一個項目,其中 sql 連接附加到各個類,因此沒有真正的方法將連接包裝在using語句中。我們不得不重新構建所有它。

如果您正在使用自定義事務或 sql 連接請求,請確保您使用 using 和try catch finally與 dispose 進行包裝。 依賴垃圾收集器並不總是很好,因為不能保證垃圾收集器會在using語句結束時立即dispose

using (var conn = new SqlConnection())
{
    try
    {
        // Transactions, SQL Commands, etc
    }
    catch (SqlException ex)
    {
        // Trans rollback, error handling
    }
    finally
    {
        // Tell the garbage collector to clean up this resource now.
        conn.Dispose();
    }
}

如果您嚴格使用數據庫上下文,則可以通過使用.AsNoTracking()對僅檢索結果集但無意修改該查詢的結果的實例稍微優化某些語句。 類似於以下內容:

var tier = _dbContext.Tier.AsNoTracking()
    .Include(t => t.NameSchema)
    .Include(t => t.TierPackageGroups)
    .Where(t => t.TierNumber == tierNumber).FirstOrDefault();

確保盡可能使用連接或.Include ,而不是延遲加載。

這不是您想聽到的答案,而且我一直站在您的立場上,但很可能最好的解決方案是通過代碼 go。 您總是可以從清理一些區域開始,測量影響,再增加一些區域,測量影響等。這種蠕變調查可以幫助您縮小搜索范圍,因為您看到某些區域有改進,或者在其他區域看不到一些。

如果您確信它必須是您想要查找的單個查詢,那么有一些工具可以評估 sql 的性能,但我通常會聘請 DBA 來處理這個問題,所以我不熟悉這些工具。 如果您使用 Azure 有一個面板,您可以在其中查看查詢並按性能影響對其進行組織。 它不會將您指向代碼,但它可以給您一個提示。

由於該問題專門針對不需要搜索代碼的解決方案,因此另一個可行的答案是在問題上投入更多硬件,但這是一個糟糕的權宜之計,可能代價高昂,最終只會延遲問題或僅在 99% 的時間內解決問題(例如,直到您遇到交通高峰期)。 我們幾年前的一位客戶可能已經花費了超過 50,000 美元的額外托管費用,而他們本可以讓我們在最初請求時以不到 5,000 美元的價格解決問題。

暫無
暫無

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

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