SQLServer zaman aşımı istisnaları nasıl yakalanır


117

Farklı şekilde ele alınabilmeleri için SQL sunucusu zaman aşımı istisnalarını özellikle yakalamam gerekiyor. SqlException'ı yakalayabileceğimi ve ardından ileti dizisinin "Zaman Aşımı" İçerdiğini kontrol edebileceğimi biliyorum, ancak bunu yapmanın daha iyi bir yolu olup olmadığını merak ediyor muydum?

try
{
    //some code
}
catch (SqlException ex)
{

    if (ex.Message.Contains("Timeout"))
    {
         //handle timeout
    }
    else
    {
         throw;
    }
}

Bir ConnectionTimeout veya CommandTimeout mu arıyorsunuz, yani bağlantının başarısız olmasını veya yürütülen komutun başarısız olmasını mı bekliyorsunuz?
edosoft

Sanırım varsayılan olarak 30
saniyeye

Yanıtlar:


157

Bir zaman aşımını kontrol etmek için eski sayı değerini kontrol ettiğine inanıyorum. Eğer -2 ise, bir zaman aşımı durumunuz var demektir.

-2, SQL Server için MDAC sürücüsü olan DBNETLIB'den döndürülen zaman aşımı için hata kodudur. Bu, Reflector indirilerek ve TIMEOUT_EXPIRED için System.Data.SqlClient.TdsEnums altına bakılarak görülebilir .

Kodunuz şöyle olacaktır:

if (ex.Number == -2)
{
     //handle timeout
}

Başarısızlığı gösteren kod:

try
{
    SqlConnection sql = new SqlConnection(@"Network Library=DBMSSOCN;Data Source=YourServer,1433;Initial Catalog=YourDB;Integrated Security=SSPI;");
    sql.Open();

    SqlCommand cmd = sql.CreateCommand();
    cmd.CommandText = "DECLARE @i int WHILE EXISTS (SELECT 1 from sysobjects) BEGIN SELECT @i = 1 END";
    cmd.ExecuteNonQuery(); // This line will timeout.

    cmd.Dispose();
    sql.Close();
}
catch (SqlException ex)
{
    if (ex.Number == -2) {
        Console.WriteLine ("Timeout occurred");
    }
}

Evet, şu anda yaptığım şey hemen hemen bu, ancak
-2'yi

12
Red Gate's Reflector'ı indirin ve TIMEOUT_EXPIRED için arama yapın. System.Data.SqlClient.TdsEnums içinde yaşar ve değeri -2'dir. : o)
Jonathan

2
Reflektöre erişimi olmayanlar için: link
ankitk

4
@brodie İşte bu yüzden onun için bir sabit yapmalısınız ve sabit üzerine bir yorum yaparak "sihirli" değerin nereden geldiğini açıklayabilirsiniz.
Jason L.

18

burada: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html Thomas Weingartner'ın yazdığını

da okuyabilirsiniz :

Zaman aşımı: SqlException.Number == -2 (Bu bir ADO.NET hata kodudur)
Genel Ağ Hatası: SqlException.Number == 11
Kilitlenme: SqlException.Number == 1205 (Bu bir SQL Server hata kodudur)

...

"Genel Ağ Hatası" nı da bir zaman aşımı istisnası olarak ele alıyoruz. Yalnızca nadir durumlarda, örneğin güncelleme / ekleme / silme sorgunuzun uzun süreli bir tetikleyici oluşturması durumunda oluşur.


6

C # 6 için güncellendi:

    try
    {
        // some code
    }
    catch (SqlException ex) when (ex.Number == -2)  // -2 is a sql timeout
    {
        // handle timeout
    }

Bakması çok basit ve güzel !!


0

SqlException.ErrorCode özelliğinin değeri nedir? Onunla çalışabilir misin?

Zaman aşımları olduğunda, -2146232060 kodunu kontrol etmeye değer olabilir .

Bunu veri kodunuzda statik bir sabit olarak kurardım.


2
ErrorCode belgelerine baktığımda, bana Interop-Düzeyinde hataları bildiriyor gibi görünüyor. Dolayısıyla, COM hataları düzeyinde daha fazla olabilir veya bir sağlayıcının yaptığınız şeyle ilgili belirli bir hata yerine bir istisna (genellikle) ile karşılaşması olabilir.
Eric Tuttleman

@Eric doğru - bu, istisnanın kaynağı için değil, SqlException türü için bir HRESULT kodudur.
codekaizen

0

Emin değilim, ancak zaman aşımı veya komut zaman aşımını yürüttüğümüzde İstemci, SQL Server'a bir "ABORT" gönderir, ardından sorgu işlemeyi bırakır. Hiçbir işlem geri alınmaz, kilitler serbest bırakılmaz. Bu sorunu çözmek için Stored-Procedure'de işlemi kaldırıyorum ve .Net Kodumda SQL Transaction'ı kullanıyorum sqlException'ı yönetmek için


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.