Das Verarbeiten von Tausenden von SqlCommands mithilfe einer SqlTransaction führt zu einer Speicherausnahme

StackOverflow https://stackoverflow.com//questions/11675430

Frage

Ich habe eine benutzerdefinierte Replikationsfunktion in einer Standard-C#-Windows-Formular-App mit einer SQL Server 2008 Express-Datenbank geschrieben.Es ruft im Wesentlichen eine Reihe von SQL-Anweisungen ab, die für eine Abonnentendatenbank ausgeführt werden müssen.Bei einer vollständigen Aktualisierung können bis zu 200.000+ Anweisungen ausgeführt werden, die ausgeführt werden müssen.

Ich verarbeite diese Anweisungen innerhalb eines Codeblocks wie unten gezeigt:

using (SqlConnection connection = ConnectionManager.GetConnection())
{
     connection.Open();

     SqlTransaction transaction = connection.BeginTransaction();

     // Process 200k+ Insert/Update/Delete statements using SqlCommands

     transaction.Commit
}

Ich stelle fest, dass die Speichernutzung meiner Anwendung bei den ersten 30.000 Anweisungen ziemlich stabil bei etwa 40 MB bleibt.Danach scheint es plötzlich auf etwa 300 MB zu springen und dann zu wachsen, bis ich auf eine OutOfMemory-Ausnahme stoße.

Ist die von mir verwendete Methode überhaupt möglich? Kann ich so viele Anweisungen in einer einzigen Transaktion verarbeiten?Ich gehe davon aus, dass ich dazu in der Lage sein sollte.Wenn es einen besseren Weg gibt, würde ich ihn gerne hier veröffentlichen.Ich benötige, dass dies transaktional ist, andernfalls würde eine teilweise Replikation zu einer beschädigten Datenbank führen.

Danke.

BEARBEITEN:

Nach dem Neustart meines Computers gelang es mir, eine vollständige Replikation mit mehr als 200.000 Dateien durchzuführen.Obwohl die Speichernutzung nach Abschluss der Replikation irgendwann auf 1,4 GB anstieg, sank die Speichernutzung wieder auf 40 MB.Daraus schließe ich, dass möglicherweise etwas in meiner Schleife, das die Befehle verarbeitet, das Speicherwachstum verursacht.

War es hilfreich?

Lösung

Bist du Disposing Ihre Formulare und die Einwegkontrollen vor dem Schließen?

Wickeln Sie alle Einwegobjekte in die Using-Anweisung ein.Klicken Sie hier für weitere Details


Öffnen/schließen Sie die Verbindung nicht immer wieder, sondern senden Sie die Daten stattdessen in einer einzigen Transaktion an die Datenbank.Klicken Sie hier für weitere Details


Da Ihre Anwendung immer noch zu viel Speicher enthält, benötigen Sie einen Doctor wie Red Gate Ants Memory Profiler.Klicken Sie hier, um weitere Details dazu zu sehen

enter image description here


Kann ich so viele Anweisungen in einer einzigen Transaktion verarbeiten?

Sie haben die folgenden Möglichkeiten, dies zu tun...

  1. Masseneinfügung und Bearbeitung der Datensätze Stored Proc.
  2. Vorbereiten XML und sende die Zeichenfolge ein Database.
  3. Senden Sie die schreibgeschützte Nachricht DataTable im SQL Server über Stored Proc

Beispiel für gespeicherte Prozesse

Begin Try
    Set NoCount ON
    Set XACT_Abort ON
    Begin TRan
        --Your queries
    Commit Tran

Begin Tran

Begin Catch
    Rollback Tran
End Catch

Stellen Sie sicher, dass Dispose die Gegenstände, sobald sie nicht verwendet werden.


Es sollte so sein

using (SqlConnection connection = new SqlConnection())
{
    connection.Open();
    using (SqlTransaction transaction = connection.BeginTransaction())
    {
        transaction.Commit();
    }
}

Haben Sie das überprüft? SqlCommand Auch?

using (SqlCommand cmd = new SqlCommand())
{
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top