Comment utiliser une seule transaction SqlTransaction pour plusieurs connexions SqlConnections dans .NET?

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

Question

  1. J'ai SQL Server 2000, il ne prend pas en charge MultipleActiveResults .
  2. Je dois faire plusieurs insertions, et cela se fait avec une connexion par insertion.
  3. Je souhaite commencer une transaction avant toutes les insertions et la terminer après toutes les insertions.
  4. Comment puis-je le faire?
Était-ce utile?

La solution

Quelle est la raison pour laquelle vous n'utilisez pas une connexion et plusieurs commandes (en fait, une commande recréée en boucle)? Peut-être que cette solution fonctionnera pour vous:

   public static void CommandExecNonQuery(SqlCommand cmd, 
       string query, SqlParameter[] prms)
    {
        cmd.CommandText = query;
        cmd.Parameters.AddRange(prms);
        cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
    }

    static void Main(string[] args)
    {
        string insertQuery = 
           @"INSERT TESTTABLE (COLUMN1, COLUMN2) " + 
             "VALUES(@ParamCol1, @ParamCol2)";
        using (SqlConnection connection = 
          new SqlConnection(connectionString))
        {
            using (SqlCommand command = 
              connection.CreateCommand())
            {
                SqlTransaction transaction = null;
                try
                {
                    // BeginTransaction() Requires Open Connection
                    connection.Open();

                    transaction = connection.BeginTransaction();

                    // Assign Transaction to Command
                    command.Transaction = transaction;
                    for (int i = 0; i < 100; i++)
                        CommandExecNonQuery(command, insertQuery, 
                          new SqlParameter[] { 
                            new SqlParameter("@ParamCol1", i), 
                            new SqlParameter("@ParamCol2", i.ToString()) });
                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    connection.Close();
                }
            }
        }
    }

Voir aussi
Transactions de serveur SQL - ADO.NET 2.0 - Validation et restauration - Utilisation Statement - IDisposable

Autres conseils

Vous n'avez pas précisé si vous utilisiez .NET 2.0, mais je vais faire cette hypothèse. Exemple de code C # 3.0 est répertorié ci-dessous:

using (var tx = new TransactionScope()) {
    // Execute multiple DB statements inside here
    ts.Complete();
}

Si l'une des instructions de la base de données échoue, le ts.complete ne sera jamais atteint et la transaction sera automatiquement annulée à la fin de l'instruction using. Toutefois, cette approche présente un inconvénient: vous utiliserez le DTC si vous utilisez plusieurs connexions, ce qui signifie des performances plus lentes.

Modifié pour changer SqlTransaction en TransactionScope

Exemple d'utilisation d'une connexion SQL unique pour éviter l'utilisation du DTC:

using (var tx = new TransactionScope())
using (var db = new SqlConnection(connString)) {
    // Command 1
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }

    // Command 2
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }

    // Command 3
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }
    tx.Complete();
}

Les transactions sont créées sur une connexion et n'ont pas de portée au-delà de la connexion sur laquelle elles sont créées, vous ne pouvez donc pas faire ce que vous demandez. Refactorisez afin que vous puissiez exécuter les insertions de manière séquentielle sur une connexion plutôt que simultanément ou implémenter un mécanisme différent pour effectuer une annulation (par exemple, une table de clés insérées pouvant être utilisée pour rechercher des enregistrements insérés si une erreur est rencontrée plus tard dans l'événement). processus)

Je ne pense pas qu'une transaction puisse couvrir plusieurs connexions.

Quel est le raisonnement pour effectuer les insertions multiples dans des connexions séparées? Je pense que vous les voudriez normalement dans une seule connexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top