Connection Pooling là kỹ thuật tái sử dụng các kết nối database đã mở thay vì tạo mới mỗi lần. Giảm chi phí overhead (handshake, authentication, allocation) và cải thiện hiệu suất đáng kể.
Cơ chế trong ADO.NET (SqlConnection)
- Mặc định: BẬT (pooling=true trong connection string).
- Khi
Open(): Lấy connection từ pool nếu có sẵn, không thì tạo mới. - Khi
Close()hoặcDispose(): Trả connection về pool (KHÔNG đóng thật sự). - Pool được quản lý per process, per connection string (exact match).
Connection String quan trọng
// Mặc định pooling=true, Min Pool Size=0, Max Pool Size=100
Server=myServer;Database=myDB;User=sa;Password=pwd;Pooling=true;Min Pool Size=5;Max Pool Size=200;
// Tắt pooling (chỉ khi cần thiết, ví dụ: admin task)
Server=myServer;Database=myDB;Pooling=false;
Best Practice: Dùng using để trả về pool đúng cách
string connString = "Server=localhost;Database=Northwind;Integrated Security=true;";
using (var conn = new SqlConnection(connString))
{
conn.Open(); // Lấy từ pool
using (var cmd = new SqlCommand("SELECT * FROM Customers", conn))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
Console.WriteLine(reader["CompanyName"]);
}
} // conn.Dispose() -> trả về pool (không đóng thật)
Các lỗi thường gặp
| Vấn đề | Nguyên nhân | Giải pháp |
|---|---|---|
| Timeout waiting for pool | Pool exhausted (Max Pool Size), leak connection | Luôn dùng using, check Max Pool Size, fix leak |
| Dùng connection đã disposed | Không lưu connection instance, mở/mỗi request | |
Quên Close()/Dispose() | using block, try/finally |
Monitoring Pool
// Performance Counters (Windows)
\\.NET Data Provider for SqlServer\NumberOfActiveConnections
\\.NET Data Provider for SqlServer\NumberOfFreeConnections
\\.NET Data Provider for SqlServer\NumberOfPooledConnections
Entity Framework Core
EF Core quản lý connection tự động: Mở trước command, đóng sau command (trả pool). Không cần can thiệp thủ công. Cấu hình pool qua DbContextOptionsBuilder:
options.UseSqlServer(connString, o => o
.MaxBatchSize(100)
.CommandTimeout(30));
// Pooling do ADO.NET provider quản lý
Async Pattern
await using var conn = new SqlConnection(connString);
await conn.OpenAsync();
await using var cmd = new SqlCommand(sql, conn);
await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) { /* ... */ }
// Tự động DisposeAsync -> trả pool
Tóm lại: Connection Pooling tự động hoạt động nếu bạn dùng using / await using đúng cách. Không cần code thêm, chỉ cần không leak connection.