Cách bắt các ngoại lệ hết thời gian chờ của SQLServer


117

Tôi cần nắm bắt cụ thể các trường hợp ngoại lệ hết thời gian chờ của máy chủ SQL để chúng có thể được xử lý theo cách khác. Tôi biết tôi có thể bắt SqlException và sau đó kiểm tra xem chuỗi thông báo có chứa "Timeout" hay không nhưng tôi đang tự hỏi liệu có cách nào tốt hơn để làm điều đó không?

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

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

Bạn đang tìm kiếm ConnectionTimeout hoặc CommandTimeout, tức là bạn đang mong đợi kết nối bị lỗi hoặc lệnh được thực thi không thành công?
edosoft 15/09/08

Tôi đang tìm CommandTimeout, được đặt ở chế độ mặc định là 30 giây, tôi nghĩ vậy
brodie

Câu trả lời:


157

Để kiểm tra thời gian chờ, tôi tin rằng bạn kiểm tra giá trị của ex.Number. Nếu nó là -2, thì bạn có một tình huống hết thời gian chờ.

-2 là mã lỗi cho thời gian chờ, được trả về từ DBNETLIB, trình điều khiển MDAC cho SQL Server. Bạn có thể thấy điều này bằng cách tải xuống Reflector và xem trong System.Data.SqlClient.TdsEnums cho TIMEOUT_EXPIRED.

Mã của bạn sẽ đọc:

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

Mã để chứng minh sự thất bại:

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

Vâng, đó là khá nhiều những gì tôi đang làm vào lúc này, nhưng nó không phải kiểm tra rất thanh lịch cho -2
Brodie

12
Tải xuống Red Gate's Reflector và tìm kiếm TIMEOUT_EXPIRED. Nó nằm trong System.Data.SqlClient.TdsEnums và giá trị của nó là -2. : o)
Jonathan

2
Đối với những người không có quyền truy cập vào Reflector: liên kết
ankitk

4
@brodie Đó là lý do tại sao bạn nên tạo một hằng số cho nó và bạn có thể giải thích giá trị "ma thuật" đến từ đâu trong một nhận xét về hằng số.
Jason L.

18

tại đây: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

Bạn cũng có thể đọc Thomas Weingartner đã viết:

Hết thời gian chờ: SqlException.Number == -2 (Đây là mã lỗi ADO.NET)
Lỗi mạng chung: SqlException.Number == 11
Chốt lại: SqlException.Number == 1205 (Đây là mã lỗi SQL Server)

...

Chúng tôi cũng xử lý "Lỗi mạng chung" như một ngoại lệ thời gian chờ. Nó chỉ xảy ra trong một số trường hợp hiếm hoi, ví dụ khi truy vấn cập nhật / chèn / xóa của bạn sẽ làm tăng kích hoạt hoạt động lâu dài.


6

Cập nhật cho c # 6:

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

Rất đơn giản và đẹp mắt !!


0

Giá trị cho thuộc tính SqlException.ErrorCode là gì? Bạn có thể làm việc với điều đó?

Khi hết thời gian chờ, bạn nên kiểm tra mã cho -2146232060 .

Tôi sẽ thiết lập điều này như một hằng số tĩnh trong mã dữ liệu của bạn.


2
Nhìn vào tài liệu cho Mã lỗi, tôi thấy có vẻ như nó đang báo lỗi Cấp độ tương tác. Vì vậy, có thể nhiều hơn ở mức độ lỗi COM hoặc nhà cung cấp gặp phải một ngoại lệ (nói chung) thay vì một lỗi cụ thể liên quan đến những gì bạn đang làm.
Eric Tuttleman

@Eric là đúng - đó là mã HRESULT cho kiểu SqlException, không phải cho nguồn của ngoại lệ.
codekaizen

0

Tôi không chắc chắn nhưng khi chúng tôi hết thời gian thực thi hoặc hết thời gian lệnh. Máy khách gửi "ABORT" đến SQL Server thì chỉ cần bỏ xử lý truy vấn. Không có giao dịch nào được quay trở lại, không có khóa nào được giải phóng. để giải quyết vấn đề này, Tôi Xóa giao dịch trong Thủ tục lưu trữ và sử dụng Giao dịch SQL trong Mã .Net của tôi Để quản lý sqlException


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.