序言 閑來無聊,前段時間發現一個.net開源框架:masa framework。經過一些小型項目使用,發現確實挺不錯的。然後我又去閱讀了整個masa framework源碼,特此來記錄整個源碼閱讀的過程。 如有錯誤之處還請指點 MASA Framework簡介 Masa Framework是 m ...
為什麼使用DbContext池?
DbContext是Entity Framework中最重要的類型之一,它提供了一種連接資料庫並執行查詢和更新的方式。在一個ASP.NET Core應用程式中,每次請求都可能需要對資料庫進行一次或多次查詢。在這種情況下,為每個請求創建新的DbContext實例並不是一個好的選擇,因為這樣做可能會導致記憶體和性能問題。
DbContext池允許應用程式在需要時重用已經創建的DbContext實例,從而提高性能並減少記憶體消耗。
性能基準
DbContext池的工作原理
DbContext池是一個對象池,它維護一組可用的DbContext實例,這些實例是預先創建好的,緩存在池子中。當應用程式需要一個新的DbContext實例時,它可以從池子中獲取一個已有的實例,使用完後再將其釋放回池子中,以供下一次使用。
DbContext池的大小是由應用程式的配置來控制的。預設情況下,DbContext池的大小是1024,但是我們也可以通過代碼進行手動配置。例如,我們可以使用以下代碼手動配置DbContext池的大小:
Services.AddDbContextPool<DbContext>(options => options.UseSqlServer(""), poolSize: 10);
在這裡,我們將DbContext池的大小設置為10個實例。
超過poolSize會怎麼樣?
微軟官網:一旦超過 poolSize,就不會緩存新的上下文實例,EF 會回退到按需創建實例的非池行為。
DbContext池中每個DbContext的生命周期
每個DbContext實例代表了應用程式與資料庫的會話(Session),池中每個DbContext實例的生命周期與依賴註入時的聲明周期有關,預設DbContext是以範圍生命周期(Scope)註冊服務的(這是最佳的方式)。
微軟官網:Entity Framework Core 不支持在同一 DbContext 實例上運行多個並行操作。 這包括非同步查詢的並行執行以及從多個線程進行的任何顯式併發使用。 因此,始終立即 await 非同步調用,或對並行執行的操作使用單獨的 DbContext 實例。
釋放DbContext池中的DbContext
官方推薦使用自定義上下文工廠:看文檔(管理共用上下文中的狀態)這裡與文檔衝突,我就不說了。
總結
DbContext池是為了提高性能而引入的概念。它可以緩存DbContext實例,避免了創建和銷毀DbContext實例的開銷,同時還可以減輕資料庫的負擔。