2013-05-16 26 views
10

Załóżmy, że używam C# do uruchomienia długo działającej procedury składowanej SQL Server (powiedzmy 30 minut). Dalej przypuśćmy, że umieszczam 1-godzinny okres czasu na kwerendzie w C# taki, że jeśli z jakiegokolwiek powodu ten SP trwa dłużej niż oczekiwano, nie kończę na mononizacji DB. Na koniec załóżmy, że ta procedura przechowywana ma blok try/catch, który przechwytuje błędy i wykonuje pewne czyszczenie w przypadku niepowodzenia jakichkolwiek kroków.Co robi program SQL Server z przekroczonym limitem czasu?

Niektóre kodu (C#):

using (SqlCommand comm = new SqlCommand("longrunningstoredproc")) 
{ 
    comm.Connection = conn; 
    comm.CommandType = CommandType.StoredProcedure; 
    comm.CommandTimeout = 3600; 
    comm.ExecuteNonQuery(); 
} 
/* Note: no transaction is used here, the transactions are inside the stored proc itself. */ 

T-SQL (w zasadzie sprowadza się do poniższych):

BEGIN TRY 
    -- initiailize by inserting some rows into a working table somewhere 
    BEGIN TRANS 
    -- do long running work 
    COMMIT TRANS 
    BEGIN TRANS 
    -- do long running work 
    COMMIT TRANS 
    BEGIN TRANS 
    -- do long running work 
    COMMIT TRANS 
    BEGIN TRANS 
    -- do long running work 
    COMMIT TRANS 
    BEGIN TRANS 
    -- do long running work 
    COMMIT TRANS 
    -- etc. 

    -- remove the rows from the working table (and set another data point to success) 
END TRY 
BEGIN CATCH 
    -- remove the rows from the working table (but don't set the other data point to success) 
END CATCH 

Moje pytanie brzmi, co będzie SQL Server zrobić z kwerendy, gdy polecenie przekracza limit czasu ze strony C#? Czy wywoła blok catch w SP, czy też po prostu odetnie go tak, że będę musiał przeprowadzić czyszczenie w kodzie C#?

+0

Polecenie nie zostanie zakończony od strony C# - baza danych będzie czas ją. Kod C# nie ma nad tym kontroli (powiedział DB do limitu czasu po 1 godzinie, a DB właśnie to robi). – Oded

Odpowiedz

5

Limit czasu jest wymuszany przez ADO.NET. SQL Server nie zna czegoś takiego jak timeout polecenia. Klient .NET wyśle ​​polecenie TDS "uwaga". Możesz zaobserwować to zachowanie za pomocą programu SQL Profiler, ponieważ ma on "uwagę".

Po odebraniu anulowania przez SQL Server zostanie anulowane aktualnie uruchomione zapytanie (tak jak w przypadku SSMS po naciśnięciu przycisku zatrzymania). Przerwa partię (tak jak w SSMS). Oznacza to, że nie można uruchomić kodu catch. Połączenie pozostanie żywe.

Z mojego doświadczenia wynika, że ​​transakcja zostanie natychmiast wycofana. Nie sądzę jednak, że jest to gwarantowane.

TL; DR: Limit czasu w ADO.NET zachowuje się tak samo, jak w przypadku naciśnięcia stop w SSMS (lub nazwie SqlCommand.Cancel).

Oto odniesienie do tego: http://blogs.msdn.com/b/psssql/archive/2008/07/23/how-it-works-attention-attention-or-should-i-say-cancel-the-query-and-be-sure-to-process-your-results.aspx

3

Limit czasu to coś, co dzieje się w połączeniu, a nie działające zapytanie.

Oznacza to, że Twój BEGIN CATCH nie zostanie wykonany w przypadku przekroczenia limitu czasu, ponieważ zapytanie nie ma o tym pojęcia.

Napisz swoje czyszczenie w języku C#, w bloku catch(SqlException ex) (testowanie limitu czasu).

Powiązane problemy