Transaction : ensemble d’opérations SQL exécutées de manière atomique. Soit tout est validé avec (Commit), soit tout est annulé en cas d’échec (Rollback), en respectant les propriétés ACID.
Sous .NET Framework/.NET, utilisez SqlTransaction (spécifique à SQL Server) pour la mise en œuvre.
Points clés du flux :
- Ouvrir la connexion base de données
conn.Open()- Démarrer la transaction depuis la connexion
conn.BeginTransaction()- Affecter l’objet transaction à
SqlCommand.Transaction- Exécuter plusieurs instructions SQL en lot
- Pas d’exception :
tx.Commit(); intercepter les exceptions :tx.Rollback()
Exemple
L’extrait original ne contient pas la logique de retour arrière dans le bloc catch, voici la version complète fonctionnelle :
public static int ExecuteSqlTran(List<string> SQLStringList)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
SqlTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
int count = 0;
for (int n = 0; n < SQLStringList.Count; n++)
{
string strsql = SQLStringList[n];
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
count += cmd.ExecuteNonQuery();
}
}
tx.Commit(); // Valider si toutes les opérations réussissent
return count;
}
catch (Exception ex)
{
tx.Rollback(); // Tout annuler à la moindre erreur
throw ex; // Relancer l’exception pour prévenir la couche supérieure
}
}
}Langage du code : C# (cs)
Cette version concatène directement des chaînes SQL et présente un risque d’injection SQL. Elle sert à comprendre le fonctionnement des transactions ; dans les projets réels privilégiez systématiquement les requêtes paramétrées.
Exemple de transaction avec requêtes paramétrées
Insertion en boucle avec SqlParameter pour contrer les injections. Points essentiels :
- Appeler
sqlCom.Parameters.Clear()à la fin de chaque itération pour effacer les anciens paramètres et éviter des erreurs d’accumulation - Réutiliser la même instance
SqlCommand, ne modifier que CommandText et les paramètres
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
SqlTransaction st = conn.BeginTransaction();
sqlCom.Transaction = st;
int res = 0;
try
{
for (int i = 0; i < 10; i++)
{
sqlCom.CommandText = "INSERT INTO [dbo].[Article]([Title])VALUES(@Title)";
SqlParameter param = new SqlParameter("@Title", SqlDbType.NVarChar, 250);
param.Value = i + "Nouveau titre" + DateTime.Now;
sqlCom.Parameters.Add(param);
res += sqlCom.ExecuteNonQuery();
sqlCom.Parameters.Clear(); // Effacer les paramètres pour l’itération suivante
}
st.Commit();
}
catch (Exception)
{
st.Rollback(); // Annuler toutes les modifications en cas d’exception
}Langage du code : C# (cs)
1. Règles obligatoires à respecter
BeginTransaction()doit être invoqué après l’ouverture de la connexion Open- Il faut renseigner la propriété
Transactionsur l’objetSqlCommand, sinon une exception sera levée - Après
Commit()/Rollback()la transaction se termine automatiquement, ne pas les appeler plusieurs fois
Divers
- Sous .NET Core/.NET 5+, préférez l’instruction
usingpour libérer automatiquementSqlTransaction - Pour des traitements par lots massifs, pensez à
SqlBulkCopy, plus performant que des appels répétés à ExecuteNonQuery SqlTransactionne gère pas les transactions inter‑bases, utilisez les transactions distribuées avecTransactionScope
SqlTransaction transactions base de données