بهینهسازی دسترسی به دادهها در NET.: راهنمای مدیریت Connection Pool در ADO.NET
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۳/۲۰ ۱۲:۵۲
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
Close() یا Dispose())، اتصال به جای اینکه به صورت فیزیکی قطع شود، به استخر بازگردانده میشود و در آنجا منتظر درخواست بعدی میماند.var connectionString = "Server=myServer;Database=myDb;User Id=myUser;Password=myPass;";
Pooling=true;: (پیشفرض) فعال یا غیرفعال کردن Connection Pooling.Min Pool Size=0;: (پیشفرض: 0) حداقل تعداد اتصالات موجود در استخر.Max Pool Size=100;: (پیشفرض: 100) حداکثر تعداد اتصالات مجاز در استخر.var connectionString = "Server=myServer;Database=myDb;User Id=myUser;Password=myPass;Pooling=true;Max Pool Size=50;";
using(var connection = new SqlConnection(connectionString))
{
connection.Open();
// اجرای دستورات...
}Close() را فراخوانی میکنید یا از ساختار using (که متد Dispose() را به صورت خودکار فراخوانی میکند) استفاده میکنید:connection.Close(); // یا اتمام بلوک using
Pooling=true;Max Pool Size=50;Min Pool Size=5;Connection Lifetime=600;
Connection Lifetime: حداکثر عمر اتصال در استخر بر حسب ثانیه را مشخص میکند. پس از این مدت، حتی اگر اتصال فعال باشد، از استخر حذف میشود.TimeoutException: زمانی که درخواست برای مدت زمان مشخصی منتظر اتصال بماند.InvalidOperationException: در برخی سناریوها ممکن است این خطا رخ دهد.Max Pool Size: در صورت نیاز و مشاهده خطاهای مرتبط با پر بودن استخر، میتوانید مقدار Max Pool Size را افزایش دهید.Connection Lifetime (عمر اتصال) یا آستانههای زمانی (Timeout Thresholds) منقضی شوند.ClearPool() یا ClearAllPools() را فراخوانی کند.SqlConnection.ClearAllPools();
[HttpGet("products")]
public IActionResult GetProducts()
{
using(var connection = new SqlConnection(_config.ConnectionString))
{
connection.Open();
using(var command = new SqlCommand("SELECT * FROM Products", connection))
using(var reader = command.ExecuteReader())
{
var products = new List<Product>();
while(reader.Read())
{
products.Add(new Product
{
Id = reader.GetInt32(0),
Name = reader.GetString(1)
});
}
return Ok(products);
}
}
}GetProducts() فراخوانی میشود:connection.Open(): ابتدا استخر را بررسی میکند.using اتصال را Dispose میکند، اتصال به استخر بازگردانده میشود.using یا Dispose() استفاده کنید: این کار تضمین میکند که اتصالات به درستی به استخر بازگردانده شوند و از نشت منابع (Resource Leaks) جلوگیری میکند.Min Pool Size و Max Pool Size را تنظیم کنید. نظارت بر عملکرد میتواند به شما در تعیین مقادیر بهینه کمک کند.Dispose کنید تا به استخر بازگردانده شود و برای سایر درخواستها در دسترس قرار گیرد.Open() و Close() اتصالات، به صورت آزادانه عمل کنند، زیرا مدیریت واقعی و پیچیده اتصالات توسط ADO.NET و در پشت صحنه (Behind the Scenes) انجام میشود و از مواردی مانند همگامسازی (Synchronization) و ایمنی رشتهای (Thread Safety) نیز مراقبت میشود.Pool Size پویا وجود دارد؟ مثلا اگر تعداد اتصالات به Max Pool Size برسه، اتصال جدید در صف قرار میگیره. خب چطور میشه بصورت دینامیکی یک Resize اتفاق بیوفته؟ به نظرم ایجاد یک کانکشن جدید شاید بهتر از در صف قرار گرفتن یک اتصال تا زمان نامعلوم باشه. چراکه اگر راهی برای ایجاد یک Max Pool Size باشه، قطعا میشه بعد از اتمام تراکنشها تعداد اتصالات موجود در استخر را به Min Pool Size کاهش داد؟LifeTime یک اتصال متوجه شدم، جدا از اینکه یک اتصال جدید باشد و یا در استخر، پس از رسیدن به مدت زمان تعیین شده (در هر دو حالت) اتصال فعال از بین خواهد رفت. آیا در اولین درخواست جهت اتصال به بانک اطلاعاتی، مجددا استخر به تعداد حداکثر تعیین شده دارای اتصال آماده خواهد بود؟TimeoutException شود.TimeoutException یا صفهای طولانی مواجه میشوید، این نشاندهنده نیاز به افزایش Max Pool Size است.TimeoutException به دلیل پر بودن استخر، میتوانید یک منطق تلاش مجدد (Retry Logic) با یک تأخیر (Delay) کوتاه پیادهسازی کنید. این کار به برنامه فرصت میدهد تا در صورت آزاد شدن یک اتصال، دوباره تلاش کند.Min Pool Size برسند. ADO.NET به صورت داخلی مکانیزمی برای مدیریت عمر اتصالات و حذف اتصالات بیکار پس از یک دوره زمانی مشخص (معمولاً در حدود 4 تا 8 دقیقه پس از آخرین استفاده) دارد. همچنین، میتوانید از پارامتر Connection Lifetime در Connection String استفاده کنید تا حداکثر مدت زمانی که یک اتصال میتواند در استخر باقی بماند را تعیین کنید.Connection Lifetime حداکثر مدت زمانی (بر حسب ثانیه) را تعیین میکند که یک اتصال میتواند در استخر فعال باقی بماند، چه این اتصال در حال استفاده باشد و چه بیکار (Idle).Connection Lifetime یک اتصال منقضی شود، آن اتصال (حتی اگر در حال حاضر فعال و در حال استفاده باشد) پس از اتمام تراکنش جاری، به جای بازگشت به استخر، از استخر حذف خواهد شد. اگر اتصال در حال استفاده نباشد، پس از اتمام عمر مفید، از استخر حذف میشود. این مکانیزم به تازه ماندن اتصالات در استخر و جلوگیری از مشکلات احتمالی ناشی از اتصالات قدیمی یا تغییرات در پایگاه داده (مانند تغییر رمز عبور یا راهاندازی مجدد سرور) کمک میکند.Max Pool Size) دارای اتصال آماده نخواهد بود.Min Pool Size نرسیده باشد).Max Pool Size) خود رشد خواهد کرد.Min Pool Size تعیین میکند که حداقل چند اتصال همیشه در استخر وجود داشته باشند، حتی اگر بیکار باشند. این اتصالات بلافاصله پس از راهاندازی برنامه (یا اولین اتصال) و در صورت عدم وجود اتصالات کافی، ایجاد میشوند تا از تأخیر اولیه در هنگام اولین درخواستها جلوگیری شود.Connection Lifetime برای تضمین "تازگی" اتصالات در استخر است، اما استخر به صورت تنبل (Lazy) و بر اساس تقاضا تا Max Pool Size رشد میکند، نه اینکه بلافاصله پس از اتمام عمر اتصالات، تمام اتصالات از دست رفته را جایگزین کند.