SqlBulkCopy.WriteToServer erfüllt BulkCopyTimeout nicht zuverlässig

8

Ich muss sequenzielle Timeout-Ausnahmen von SqlBulkCopy zählen. Um dies zu testen, verwende ich eine externe App, um eine Transaktion zu starten. Sperrt die Zieltabelle.

Nur beim ersten Aufruf gibt SqlBulkCopy eine erwartete Zeitüberschreitungsausnahme aus. Wir haben versucht, eine externe Verbindung zu verwenden. Transaktion, sowie eine Verbindungszeichenfolge und interne Transaktion verwenden. Mit der externen Verbindung & amp; Transaktion, die unendliche Wartezeit war nie beim Öffnen der Verbindung oder beim Beginnen oder bei der Übergabe der Transaktion, sondern immer bei .WriteToServer() .

Gibt es einen Ansatz, bei dem SqlBulkCopy.WriteToServer() zuverlässig eine Zeitüberschreitungsausnahme auslöst, wenn es sein .BulkCopyTimeout -Grenze erreicht hat?

%Vor%

Ich bevorzuge es, Ausnahmen im Rahmen des Blocks using aufblähen zu lassen, anstatt sie zu behandeln, aber ich kann immer wieder neu beginnen. Vielen Dank für jede Einsicht.

Update 1:

Immer noch keine Lösung. Interessantes Verhalten, das dennoch entdeckt wird - ein normaler SqlCommand löst eine TimeoutException erwartungsgemäß während derselben Sperre aus, die die SqlBulkCopy.WriteToServer-Methode auf unbestimmte Zeit blockiert.

Hier sind die Ansätze, die wir versucht haben - und die fehlgeschlagen sind - SqlBulkCopy.WriteToServer zu veranlassen, Zeitüberschreitungen zu erwarten, wenn sie erwartet werden:

  • MARS (Mehrere aktive Ergebnismengen) ein / aus
  • TableLock on vs. off
  • Ziel als Heap-Tabelle im Vergleich zur indizierten Tabelle
  • Längere / kürzere BulkTimeout-Werte (10 Sekunden bis 5 Minuten)
  • Interne vs externe Transaktion

Als Workaround wechsle ich vorerst zwischen a) dem Aufruf von WriteToServer in einem asynchronen Wrapper, damit ich es selbst einstellen kann und b) nur einmal WriteToServer aufrufen; Warten Sie nach Timeouts, bis ein regulärer SqlCommand erfolgreich ist , bevor Sie WriteToServer erneut versuchen. Mit diesen Ansätzen bin ich zumindest in der Lage, den Ausführungsfluss zu kontrollieren.

    
Paul Smith 05.02.2010, 18:23
quelle

2 Antworten

4

Haben Sie versucht, die SqlBulkOptions.TableLock-Option an SqlBulkCopy zu übergeben? Diese Option (Zitat) bedeutet, dass es:

  

Erhalten Sie eine Massenaktualisierungssperre für die   Dauer der Massenkopieoperation.

Wenn es also eine andere Verarbeitung gibt, die die Tabelle sperrt, würde dies verhindern, dass die Sperre erreicht wird, und theoretisch eine zuverlässige Zeitüberschreitung.

Aktualisierung:
Ich habe mein eigenes Testgeschirr aufgebaut und kann nicht reproduzieren. Um die Tabelle zu sperren, habe ich eine Transaktion in SSMS mit SELECT * FROM TargetTable WITH (HOLDLOCK) gestartet. Ich habe die gleiche BulkCopy-Methode verwendet, die Sie in die Frage einbezogen haben, indem Sie interne Transaktionen mit einem Zeitlimit für das Massenladen von 30 Sekunden verwenden. Jeder Versuch, die Massenkopie durchzuführen, wird nach 30 Sekunden wie erwartet abgebrochen. Es ist dann erfolgreich, wenn ich die SSMS-Transaktion zurücksetze.

Ich verwendete SQL Server 2008 Express, .NET 3.5.

Es ist nicht so wie nach dem ersten Versuch, das Zeitlimit für Massenladevorgänge wird nicht korrekt übergeben? es ist nicht irgendwie auf "unbestimmt" eingestellt.

Update 2:
Auch eingeschaltet mehrere Active Result Sets unterstützt in der Verbindungszeichenfolge, immer noch für mich jedes Mal Zeitüberschreitung.

    
AdaTheDev 05.02.2010, 18:29
quelle
1

Ich hatte dieses Problem zuletzt und für die Lösung dieses Problems setzte BulkCopyTimeout auf Null.

%Vor%     
masoud ramezani 07.02.2010 05:34
quelle