2013-05-16 3 views
10

Angenommen, ich verwende C#, um eine lange gespeicherte SQL Server-Prozedur auszuführen (etwa 30 Minuten). Nehmen wir weiter an, dass ich die Abfrage in C# mit einer 1-Stunden-Timeout-Periode versehen habe, so dass ich, wenn dieser SP aus irgendeinem Grund länger als erwartet dauert, die DB nicht monopolisieren werde. Nehmen wir zum Schluss an, dass diese gespeicherte Prozedur einen try/catch-Block enthält, um Fehler zu erkennen und eine Bereinigung durchzuführen, falls irgendwelche Schritte darin fehlschlagen sollten.Was macht SQL Server mit einer zeitgesteuerten Anfrage?

Einige Code (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 (beträgt grundsätzlich folgende):

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 

Meine Frage ist, was wird SQL Server mit der Abfrage zu tun, wenn der Befehl Zeiten von der C# -Seite aus? Wird es den catch-Block des SP aufrufen, oder schneidet es es einfach so ab, dass ich die Bereinigung im C# -Code durchführen müsste?

+0

Der Befehl wird nicht von der C# Website Timeout - Die Datenbank wird es eine Zeitüberschreitung. Der C# -Code hat keine Kontrolle darüber (der DB wurde gesagt, dass er nach 1 Stunde Timeout hat, und die DB tut genau das). – Oded

Antwort

5

Die Zeitüberschreitung wird von ADO.NET erzwungen. SQL Server kennt keine Befehlsüberschreitung. Der .NET-Client sendet einen TDS-Befehl "Achtung". Sie können dieses Verhalten mit SQL Profiler beobachten, da es ein "Aufmerksamkeit" -Ereignis hat.

Wenn SQL Server die Stornierung empfängt, wird die aktuell ausgeführte Abfrage abgebrochen (genau wie SSMS, wenn Sie die Stopp-Schaltfläche drücken). Es wird den Batch abbrechen (genau wie in SSMS). Dies bedeutet, dass kein Fangcode ausgeführt werden kann. Die Verbindung wird am Leben bleiben.

Nach meiner Erfahrung wird die Transaktion sofort zurückgesetzt. Ich denke nicht, dass das garantiert ist.

TL; DR: Ein Timeout in ADO.NET verhält sich genauso, als ob Sie Stop in SSMS gedrückt hätten (oder SqlCommand.Cancel genannt).

ist hier Referenz für diese: 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

Das Zeitlimit tritt bei der Verbindung auf, nicht bei der laufenden Abfrage.

Das bedeutet, dass Ihr BEGIN CATCH wird im Falle einer Zeitüberschreitung nicht ausgeführt werden, da die Abfrage keine Ahnung davon hat.

Schreiben Sie Ihre Bereinigung in C#, in einem catch(SqlException ex) Block (Testen für eine Zeitüberschreitung).