wake-up-neo.com

Fehler - Die Transaktion, die der aktuellen Verbindung zugeordnet ist, wurde abgeschlossen, aber noch nicht entsorgt

Ich habe Probleme mit der Variablen TransactionScope, um mehrere Datenbankabfragen in eine Transaktion einzuwickeln. Ich verwende SqlBulkCopy mit Batchgröße 500. Wenn ich die Stapelgröße auf 1000 erhöht habe, erhalte ich den Fehler

Die mit der aktuellen Verbindung verbundene Transaktion wurde abgeschlossen wurde aber nicht entsorgt. Die Transaktion muss vor dem .__ abgewickelt werden. Mit connection können SQL-Anweisungen ausgeführt werden.

Dies ist der Code, den ich verwende:

using (var scope = new TransactionScope())
{
    using (var connection = (SqlConnection)customerTable.OpenConnection())
    {
        var table1BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName1
        };

        table1BulkCopy.WriteToServer(table1DataTable);

        var table2BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName2
        };

        table2BulkCopy.WriteToServer(table2DataTable);

        var table3BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName3
        };

        table1BulkCopy.WriteToServer(table3DataTable);

        var table4BulkCopy = new SqlBulkCopy(connection)
        {
            BatchSize = BATCH_SIZE,
            DestinationTableName = TableName4
        };

        table4BulkCopy.WriteToServer(table4DataTable);

        scope.Complete();
    }
}
58
Pradeep

Dies kann passieren, wenn die Transaktion abläuft. Sie können das Timeout für Ihre Transaktion so erhöhen (verwenden Sie Werte, die der erwarteten Länge Ihrer Transaktion entsprechen). Der folgende Code gilt für 15 Minuten:

using (TransactionScope scope = 
             new TransactionScope(TransactionScopeOption.Required, 
                                   new System.TimeSpan(0, 15, 0)))
  {
      // working code here
  }

Deshalb hätte es für Chargengröße 500 und nicht für 1000 funktionieren können.

104
Anthony Queen

Das Festlegen des Timeouts im TransactionScope hat für mich nicht funktioniert. Ich musste außerdem den folgenden Konfigurationsschlüssel an das Ende des Tag "machine.config <configuration>" hinzufügen, um das standardmäßige Timeout von 10 Minuten zu überschreiten.

<system.transactions>
    <machineSettings maxTimeout="00:30:00" /> <!-- 30 minutes -->
</system.transactions>

Bildnachweis: http://thecodesaysitall.blogspot.com.au/2012/04/long-running-systemtransactions.html

18
Adam

Bewegen Sie scope.Complete(); außerhalb des connection-Blocks.

using (var scope = new TransactionScope())
{
  using (var connection = (SqlConnection)customerTable.OpenConnection())
   {
    //
   }
  scope.Complete();
}
7
adatapost

Ein offensichtliches Problem mit der Zeitüberschreitung, aber Sie erhalten keine Wirkung, wenn Sie TransactionOptions.Timeout höher setzen. Es spielt keine Rolle, dass die Timeout-Eigenschaft der TransactionOptions auf einen höheren Wert gesetzt wird, TransactionOptions.Timeout darf die maxTimeout-Eigenschaft nicht überschreiten. Sie sollten einige Änderungen in machine.config vornehmen.

In Kürze sollten Sie die Datei machine.config % Windir%\Microsoft.NET\Framework\Ihre Version\config\machine.config .__ finden.
Und füge dies im <configuration>-Tag hinzu:

<system.transactions>
    <machineSettings maxTimeout="00:30:00"/>
</system.transactions>

Hier können Sie die Eigenschaft maxTimeout auf 30 Minuten einstellen.
Weitere Informationen finden Sie im Folgenden. http://thecodesaysitall.blogspot.com/2012/04/long-running-systemtransactions.html

0
Vortman

Die vollständige Antwort muss voller sein.

Sie müssen angeben, wo die maximale Transaktionszeitüberschreitung ermittelt wird, im .Net-Code oder in der Serverkonfiguration

<sectionGroup name="system.transactions".... 
    ...allowDefinition="MachineOnly"
</sectionGroup>

In diesem Fall können Sie in der machine.config ein maximales Timeout einstellen

<configuration>
 <system.transactions>
 <machineSettings maxTimeout="01:00:00" />
 </system.transactions>
</configuration> 

Oder Sie möchten dieses Verhalten in der Anwendung überschreiben. Dann In der machine.config sollten Sie die Geschwindigkeit einstellen:

...allowDefinition="MachineToApplication"

Dies ist ein guter Artikel: https://blogs.msdn.Microsoft.com/ajit/2008/06/18/override-the-system-transactions-default-timeout-von-10-minuten-in- code/

0