Dapper ve SQL Server ile Bağlantı Yönetimi

1. Giriş

ASP.NET Core + Dapper projelerinde sık karşılaşılan bir hata: “The semaphore timeout period has expired.”

Bu hata çoğunlukla yanlış bağlantı yönetiminden kaynaklanır. Birçok projede KapaliysaAc() gibi metotlarla tek bir IDbConnection nesnesi sürekli açık tutulur. Kısa vadede pratik gibi görünse de, uzun vadede bağlantı hataları, timeout sorunları ve performans kayıpları yaratır.

2. Semaphore Timeout’u Basitçe Anlamak

  • Semaphore: İşletim sisteminde kaynak erişimini yöneten bir işaret mekanizmasıdır.
  • SQL bağlantıları da bu mekanizmayla yönetilir.
  • Eğer SQL Server’dan belirlenen süre içinde yanıt gelmezse işletim sistemi beklemeyi keser ve hata fırlatır: “The semaphore timeout period has expired.”

👉 Özetle: Uygulama SQL’den veri bekler, ama bağlantı bozulduğu veya yanıt geciktiği için işletim sistemi süreyi doldurur ve hata üretir.

3. Yanlış Yöntem: KapaliysaAc()


private void KapaliysaAc()
{
    if (db.State != ConnectionState.Open) db.Open();
}

Bu kodda amaç, aynı IDbConnection nesnesini sürekli açık tutarak tekrar tekrar new SqlConnection yazmaktan kaçınmaktır. Ama bu yöntem ciddi sorunlara yol açar.

⚠️ Neden KapaliysaAc() Tehlikeli?

1. Bağlantı bozulsa bile .State = Open görünebilir

Network kesintisi veya SQL Server reseti sonrası bağlantı kopabilir. Ama SqlConnection.State hala Open dönebilir. Kodun sorgu atar, ama aslında ölü bir connection üzerinden işlem yapmaya çalışır. Sonuç: Yanıt gelmez → timeout hatası.

2. Connection sürekli açık kalır, pooling avantajı kaybolur

ADO.NET connection pool kullanır: her new SqlConnection aslında havuzdan sağlam bir bağlantı alır. Ama tek bir connection’ı hep açık tutarsan, havuz devreye giremez. Bozulmuş bir bağlantıyı kullanmaya devam edersin. Bu da transport-level error ve semaphore timeout hatalarının temel sebebidir.

3. Uzun süre açık kalan bağlantılar timeout üretir

SQL Server, firewall veya proxy uzun süre kullanılmayan bağlantıları kapatabilir. Ama nesne hala “açığım” der. İlk sorguda cevap gelmez → işletim sistemi bekler → süre dolunca “semaphore timeout expired”. Özellikle yüksek trafikli projelerde bu hata sık görülür.

3.1. Uzun Süre Boşta Kalan Uygulamalar

Eğer uygulamanız 10 dakika boyunca hiç kullanılmazsa (hiç SQL sorgusu atılmazsa), bağlantı “idle” durumda kalır. Çoğu ortamda SQL Server veya aradaki ağ cihazları bu bağlantıyı otomatik olarak kapatır. Fakat uygulamanızdaki connection nesnesi hala Open görünür. İlk yeni sorguda aslında ölü bir bağlantı kullanılacağı için “timeout / semaphore expired” hatası alırsınız.

👉 Çözüm: Her sorguda using ile yeni bir connection açmak. Connection pool bozuk olanı atar, sağlam bir bağlantı verir. Böylece uygulama 10 dakika değil, 1 saat boşta kalsa bile sorun yaşamaz.

3.2. Execution Timeout Expired

Bazı durumlarda hatanın tam metni “Execution Timeout Expired” olur. Bu durumda sorun genellikle iki ihtimalden kaynaklanır:

  • Sorgu gerçekten uzun sürüyor (index eksikliği, büyük dataset, karmaşık joinler).
  • Connection bozuk olduğu için SQL Server’a hiç ulaşamıyor, bekleme süresi doluyor.

Her iki senaryoda da kalıcı çözüm, her sorguda using ile yeni bir bağlantı açmak ve gerekiyorsa commandTimeout parametresini ayarlamaktır.

4. Doğru Yöntem: using Pattern

ADO.NET’in connection pool özelliği sayesinde her new SqlConnection hızlıdır. En güvenli yol: Her sorguda connection açıp kapatmak.


public IEnumerable GetDeals(Guid tenantId)
{
    using var conn = new SqlConnection(_connectionString);

    return conn.Query(
        "SELECT Id, Adi FROM temel.Deals WHERE TenantId=@TenantId",
        new { TenantId = tenantId }
    );
}
  • Her method sonunda bağlantı otomatik kapanır.
  • Semaphore timeout ve execution timeout hataları büyük ölçüde ortadan kalkar.
  • Kod daha temiz ve öngörülebilir olur.

5. İpuçları

  • SELECT * yerine sadece gerekli kolonları seçin.
  • Büyük tablolarda TOP / OFFSET ile sayfalama yapın.
  • Uzun sürecek sorgular için commandTimeout parametresini kullanın.
  • SQL tarafında index optimizasyonlarını kontrol edin.

6. Sonuç

KapaliysaAc() gibi metotlar kısa vadede pratik görünse de, uzun vadede bağlantı problemleri ve timeout hataları üretir.

✅ Çözüm: Her sorguda using ile connection açıp kapatın. Dapper ve ADO.NET’in connection pool mekanizması sayesinde bu yöntem hem güvenli, hem de performanslıdır.

👉 Bu rehberi ekibinle paylaşırsan, semaphore timeout ve execution timeout hatalarının büyük çoğunluğu kaybolacaktır.

Telefon +90 505 747 42 84
Email info@devedijital.com
Adres
Tacettin Veli Mahallesi Halit Narin Caddesi Bahadır Plaza Kat:11 Daire:41 38230 Deve Dijital Melikgazi/Kayseri/Türkiye