web-dev-qa-db-fra.com

Error - La transaction associée à la connexion en cours est terminée mais n'a pas été supprimée.

J'ai eu du mal à utiliser la variable TransactionScope pour envelopper plusieurs requêtes de base de données dans une transaction. J'utilise SqlBulkCopy avec batchsize 500. Lorsque j'ai augmenté la taille du lot à 1000, le message d'erreur suivant s'affiche:

La transaction associée à la connexion en cours est terminée mais n'a pas été éliminé. La transaction doit être réglée avant le connexion peut être utilisé pour exécuter des instructions SQL.

C'est le code que j'utilise:

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

Cela peut arriver lorsque la transaction arrive à expiration. Vous pouvez augmenter le délai d'expiration de votre transaction comme ceci (utilisez des valeurs appropriées pour la durée attendue de votre transaction). Le code ci-dessous est pour 15 minutes:

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

C'est pourquoi il aurait pu fonctionner pour une taille de lot de 500 et non pour une taille de 1000.

104
Anthony Queen

J'ai constaté que le réglage du délai d'attente dans TransactionScope ne fonctionnait pas pour moi. J'avais également besoin d'ajouter la clé de configuration suivante à la fin de la balise machinecode.config <configuration> pour dépasser le délai d'expiration maximal par défaut de 10 minutes.

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

Crédit: http://thecodesaysitall.blogspot.com.au/2012/04/long-running-systemtransactions.html

18
Adam

Déplacez scope.Complete(); en dehors du bloc connection.

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

Problème assez évident avec le délai d’expiration, mais vous n’obtenez pas d’effet si vous définissez TransactionOptions.Timeout plus élevé . Même si vous définissez TimeSpan.MaxValue, vous n’obtenez pas de profit. Peu importe que la propriété Timeout de TransactionOptions soit définie sur une valeur plus élevée, TransactionOptions.Timeout ne peut pas dépasser la propriété maxTimeout. Vous devez configurer certaines modifications dans machine.config.

Vous devriez bientôt trouver le fichier machine.config % Windir%\Microsoft.NET\Framework\votre version\config\machine.config
Et ajoutez ceci dans la balise <configuration>:

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

Ici, vous pouvez définir la propriété maxTimeout sur 30 minutes.
Voir ci-dessous pour plus de détails http://thecodesaysitall.blogspot.com/2012/04/long-running-systemtransactions.html

0
Vortman

La réponse complète doit être plus complète.

Vous devez spécifier - où sera déterminé le délai de transaction maximal - dans le code .Net ou dans la configuration du serveur.

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

Dans ce cas, vous pouvez définir le délai maximal dans le fichier machine.config.

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

Ou peut-être souhaitez-vous remplacer ce comportement dans l'application. Ensuite, dans le fichier machine.config, vous devez définir la valeur du velue:

...allowDefinition="MachineToApplication"

C'est un bon article: https://blogs.msdn.Microsoft.com/ajit/2008/06/18/override-the-system-transactions-default- timeout-of-10-minutes-in-the- code/

0
Alexander Shapkin