Erzwingen eines Abfragezeitlimits in SQL Server


79

Wir hatten ein Problem mit einem Codeblock, der angesichts langsamer Datenbanken schlecht reagiert (bei einem Abfrage-Timeout wird das Bett kaputt gemacht). Wir haben einen Patch erstellt und führen ihn gerade durch die Regression.

Wir können keine Auszeit bekommen. Ich habe eine Transaktion aus SQL Mgmt Studio geöffnet und jede Zeile aktualisiert, um sie zu sperren, aber das führt nicht zu einer Zeitüberschreitung bei INSERTs (was ich brauche).

Kann ich über T-SQL problemlos eine Sperre auf Tabellenebene erhalten? Oder muss ich im Meister herumspielen? Oder kann ich das Timeout einfach erzwingen, ohne es zu sperren? Jede Eingabe wird geschätzt.

Antworten:


131

Führen Sie dies aus und versuchen Sie dann Ihre Beilage ...

select * from yourTable with (holdlock,tablockx)

Hier können Sie es für 5 Minuten sperren:

BEGIN TRANSACTION

SELECT * FROM yourTable WITH (TABLOCKX, HOLDLOCK)

WHERE 0 = 1

WAITFOR DELAY '00:05'

ROLLBACK TRANSACTION

Gibt es eine Möglichkeit, dies von C # /. NET aus zu tun, ohne den Thread zu blockieren, der diesen Aufruf von SQL Server ausgeführt hat? Ich versuche, das Verhalten meiner Anwendung zu testen, wenn die Verbindungszeit abgelaufen ist. Wenn ich diesen Code von C # aus aufrufe, weiß ich nicht, wie ich eine weitere Abfrage ausführen soll, um das Zeitlimit gezielt zu ermitteln.
Jake Smith

33

Sie können Ihrem SQL-Code einfach sagen, dass er eine Minute warten soll, bevor er zurückkehrt:

WaitFor Delay '00:01:00'

Gewählt für die Einfachheit der Antwort. Ich habe es getestet und es funktioniert
Mikel

Ich füllte eine Tabelle und erstellte komplexe rekursive Abfragen, Buff, Unsinn. Das macht den Trick.
DanielV

10

Auf der anderen Seite: Wenn die Verbindung konfigurierbar ist, reduzieren Sie das Zeitlimit für die Verbindungszeichenfolge auf 1 Sekunde - das macht es einfacher. Füllen Sie die Tabelle mit Unmengen von Daten und lassen Sie 3 andere Prozesse in einer Schleife drehen, um Teile dieser Tabelle mit einer Transaktion um die Schleife zu aktualisieren. Ändern Sie nicht die von der App aufgerufene tatsächliche Prozedur (Injizieren von Waitfor). Das macht einen Integrationstest ungültig.

Dies ist jedoch eine Fallstudie zugunsten von Unit-Tests und Abhängigkeitsinjektionen. Einige Dinge sind nur schwer zu integrieren. Unit Test + Abhängigkeitsinjektion .

  • Real: Code, der scheißt -> Datenbank-Timeout (schwer zu reproduzieren).
  • Refactor: Code, der scheißt -> Repository (nur Datenzugriff) -> Datenbank
  • Unit Test: Code, der Craps> Mock Repository zu werfen -> null
  • Jetzt haben Sie einen fehlgeschlagenen Test für Code, der Fehler macht und ihn beheben kann.

Dies ist eine "Abhängigkeits" -Injektion. Der Entwickler kann die Abhängigkeit in die Datenbank einfügen und etwas ersetzen, das das Verhalten einer Abhängigkeit simuliert. Gut für alle Datenbanktests. Wenn der Komponententest eingerichtet ist, wissen Sie, dass das Update genau das tut, was es sollte, aber Sie benötigen noch einen Integrationstest. In diesem Fall kann es sich besser auf die Regression konzentrieren - was bedeutet, dass beim Testen nichts anderes beschädigt wurde und die Funktion weiterhin funktioniert.

Sie haben Ihren Patch bereits erstellt, daher ist meine Antwort wohl zu spät.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.