Cara menangkap pengecualian waktu tunggu SQLServer


117

Saya perlu secara khusus menangkap pengecualian waktu tunggu server SQL sehingga mereka dapat ditangani secara berbeda. Saya tahu saya bisa menangkap SqlException dan kemudian memeriksa apakah string pesan Mengandung "Timeout" tetapi bertanya-tanya apakah ada cara yang lebih baik untuk melakukannya?

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

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

Apakah Anda mencari ConnectionTimeout atau CommandTimeout, yaitu apakah Anda mengharapkan koneksi gagal atau perintah yang dijalankan gagal?
edosoft

Saya mencari CommandTimeout, yang disetel ke default 30 detik menurut saya
brodie

Jawaban:


157

Untuk memeriksa batas waktu, saya yakin Anda memeriksa nilai ex.Number. Jika -2, maka Anda memiliki situasi batas waktu.

-2 adalah kode galat untuk batas waktu, dikembalikan dari DBNETLIB, driver MDAC untuk SQL Server. Ini dapat dilihat dengan mengunduh Reflector , dan mencari di bawah System.Data.SqlClient.TdsEnums untuk TIMEOUT_EXPIRED.

Kode Anda akan berbunyi:

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

Kode untuk menunjukkan kegagalan:

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");
    }
}

Ya, itulah yang saya lakukan saat ini, tetapi pemeriksaannya tidak terlalu elegan untuk -2
brodie

12
Unduh Red Gate's Reflector, dan cari TIMEOUT_EXPIRED. Itu tinggal di System.Data.SqlClient.TdsEnums, dan nilainya -2. : o)
Jonathan

2
Bagi mereka yang tidak memiliki akses ke Reflector: link
ankitk

4
@brodie Itulah mengapa Anda harus membuat konstanta untuk itu dan Anda dapat menjelaskan dari mana asal nilai "ajaib" dalam komentar tentang konstanta.
Jason L.

18

di sini: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

Anda juga dapat membaca bahwa Thomas Weingartner menulis:

Batas waktu: SqlException.Number == -2 (Ini adalah kode kesalahan ADO.NET)
Kesalahan Jaringan Umum: SqlException.Number == 11
Kebuntuan: SqlException.Number == 1205 (Ini adalah kode kesalahan SQL Server)

...

Kami menangani "Kesalahan Jaringan Umum" sebagai pengecualian waktu tunggu juga. Ini hanya terjadi dalam keadaan yang jarang terjadi misalnya ketika kueri perbarui / sisipkan / hapus akan memunculkan pemicu yang berjalan lama.


6

Diperbarui untuk c # 6:

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

Sangat sederhana dan bagus untuk dilihat !!


0

Apa nilai properti SqlException.ErrorCode? Bisakah Anda bekerja dengan itu?

Saat memiliki waktu tunggu, mungkin ada baiknya memeriksa kode untuk -2146232060 .

Saya akan mengatur ini sebagai konstanta statis dalam kode data Anda.


2
Melihat dokumen untuk ErrorCode, menurut saya ini melaporkan kesalahan Interop-Level. Jadi mungkin lebih pada tingkat kesalahan COM atau penyedia menemukan pengecualian (umumnya) daripada kesalahan khusus yang berkaitan dengan apa yang Anda lakukan.
Eric Tuttleman

@Eric benar - itu adalah kode HRESULT untuk tipe SqlException, bukan untuk sumber pengecualian.
codekaizen

0

Saya tidak yakin tetapi ketika kita telah mengeksekusi waktu habis atau waktu perintah habis Klien mengirimkan "ABORT" ke SQL Server kemudian meninggalkan pemrosesan kueri. Tidak ada transaksi yang dibatalkan, tidak ada kunci yang dilepaskan. untuk mengatasi masalah ini saya Hapus transaksi di Stored-procedure dan gunakan SQL Transaction di .Net Code saya Untuk mengelola sqlException


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.