|
|
2019-11-18 tarihinde 14:41:59 tarihinde yayınlandı
|
|
|

DbContextPool, ASP.NET Core 2.1'de tanıtılan ve DbContext örneği oluşturma yükünü azaltan yeni bir özelliktir, ancak içinde gizli küçük bir çukur vardır. Son zamanlarda, bir ASP.NET Core projesi bir süre boyunca kesintisiz çalıştı ve ardından veritabanı bağlantı havuzunun maksimum bağlantı sayısına ulaştığına dair bir hata çıktı:
System.InvalidOperationException: Timeout expired. 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. at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e) Başta, DbContext'in doğru şekilde dağıtılmasına neden olan bir kod olduğunu düşündüm ama kodda hiçbir ipucu bulamadım. Daha sonra şüphe edilecek başka bir şey kalmadı, sadece DbContextPool, bu yüzden DbContextPool'u kaldırmaya çalıştım ama hata kayboldu. Gerçekten DbContextPool tarafından neden oldu, ama insanları merak ettiren şey, DbContextPool'un aslında DbContext örnekleri oluşturma yükünü azaltmak için tasarlandığı, peki nasıl daha fazla veritabanı bağlantısı tüketebilir ve bu projenin yükü çok düşük ve tüm bağlantı havuzunu nasıl tüketebilir? Bugün haftalık toplantıda bu garip sorundan bahsettim ve sonra aniden her DbContext örneğinin bir veritabanı bağlantısını (SqlConnection) işgal edeceğini düşündüm ve DbContextPool etkinleştirilmediğinde, istek biter bitmez ilgili DbContext örneği ortadan kaldırılır ve veritabanı bağlantısı tekrar bağlantı havuzuna konur. DbContextPool kullanıldığında, DbContext elden çıkarılmaz, istek bittikten sonra tekrar DbContextPool'a konur ve DbContext kendi havuzuna geri konur; bu da ilgili veritabanı bağlantısının ait olduğu bağlantı havuzuna geri dönmeyeceği anlamına gelir. DbContextPool'daki her DbContext bir veritabanı bağlantısına karşılık gelir ve DbContextPool'daki her ek DbContext için, veritabanı bağlantı havuzunda bir veritabanı bağlantısı azalır. İki havuz farklı boyutlarda olduğunda ve DbContextPool veritabanı bağlantı havuzundan büyük olduğunda, sorun ortaya çıkar; DbContextPool kendi havuzunun büyüklüğüne göre (diyelim ki 128) DbContext'i havuza serbestçe doldurur, veritabanı bağlantı havuzunun büyüklüğünü görmezden gelir (varsayılarak 100 sayılırsa) ve yukarıdaki hata 101. DbContext dolduğunda ortaya çıkar. Bu proje varsayılan ayarları kullanıyor, varsayılan ayar bu sorunu tetikliyor mu?
DbContextPool uygulama kaynak koduna bakıldığında, keşif havuzu için varsayılan boyut sınırı 128'dir
SqlConnention'ın uygulama kaynak koduna baktığınızda, bağlantı havuzları için varsayılan boyut sınırının 100 olduğunu göreceksiniz
Varsayılan ayar sorunu tetikliyor, ki bu aslında küçük bir tuzak.
Nedeni bilindiğinde, çözüm basittir: DbContextPool'un poolSize'ini veritabanı bağlantı havuzunun Max_Pool_Size altında ayarlayın
|
Puan
-
Tüm puanları gör
Önceki:C#, IsAssignableFrom, IsSubclassOf belirlenmesini devralırÖnümüzdeki:MySQL Entity Framework Core istisna çözüm
|