Ma compréhension d'une transaction est que ce sont une ou plusieurs commandes SQL qui seront toutes exécutées en tant que groupe.
Maintenant, je lis la documentation de Microsoft et je ne comprends pas le but du premier bloc d'exceptions try-catch . Pourquoi essayerions-nous d'annuler la transaction si elle échoue. Ce que je veux dire, c'est que si cela échoue, ne devrions-nous pas être sûrs qu'aucun changement n'a été fait dans la base de données (puisque c'est le but d'une transaction)? Qu'est-ce que je ne comprends pas?
private static void ExecuteSqlTransaction(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction("SampleTransaction");
// Must assign both transaction object and connection
// to Command object for a pending local transaction
command.Connection = connection;
command.Transaction = transaction;
try
{
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
command.ExecuteNonQuery();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
Console.WriteLine("Both records are written to database.");
}
catch (Exception ex)
{
// Logging exception details
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
// Logging exception details
}
}
}
}
4 Réponses :
La restauration d'une transaction annulera tout ce que vous avez fait dans le cadre de cette transaction. Donc, si vous démarrez une transaction, insérez quelques enregistrements dans une table, effectuez une mise à jour d'un enregistrement et que la mise à jour échoue, la restauration supprimera également les enregistrements insérés.
Je comprends l'objectif de la fonction de restauration. Ce que je n'ai pas compris, c'est pourquoi doit-il être appelé SI nous savons que l'opération de validation a échoué. Si la validation échoue, aucune de ces modifications n'aurait dû se produire dans le tableau en premier lieu
Vous devez mettre fin à la transaction avec la restauration ou la validation. Si le commit échoue vous devez retourner, de sorte que la transaction n'est pas ouverte, ce qui peut naturellement causer une multitude de problèmes. P>
Je suppose que c'est la raison pour laquelle il est préférable d'utiliser la directive Using ! Merci!
Vous pouvez également consulter le système . transactions.transactionscope
il peut être utilisé dans une utilisation et s'il n'est pas terminé, il sera restauré sans avoir besoin d'une commande d'annulation.
Je vais regarder ça!
Selon le Documentation Microsoft que vous avez liée:" La transaction est annulée en cas d'erreur, ou si elle est supprimée sans avoir été préalablement validée . " [Je souligne]. Je m'attendrais donc à ce que ce qui suit fonctionne aussi:
private static void ExecuteSqlTransaction(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
using (SqlTransaction transaction connection.BeginTransaction("SampleTransaction"))
{
// Must assign both transaction object and connection
// to Command object for a pending local transaction
command.Connection = connection;
command.Transaction = transaction;
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
command.ExecuteNonQuery();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
Console.WriteLine("Both records are written to database.");
}
}
}
Notez qu'il n'y a pas d'appel Rollback explicite ici.
Parce que j'ai mis SqlTransaction dans un bloc using a, il sera toujours éliminé, même si une exception est levée . Si l'exécution se déroule normalement, "transaction.Commit ()" validera la transaction. Cependant, si une exception est levée et que nous n'obtenons pas l'appel Commit (), alors la transaction ne sera pas validée, mais elle sera toujours supprimée (en quittant la portée du bloc using). Et nous savons d'après la documentation que la transaction sera annulée si elle est supprimée sans avoir été préalablement validée, ou même en cas d'erreur.
Il n'est pas nécessaire d'attraper une exception ici, car nous ne pouvons pas faire n'importe quoi à l'exception. Je m'attendrais à ce que l'exception soit gérée quelque part plus haut dans la chaîne d'appel, par exemple, là où elle pourrait être enregistrée et un message d'erreur convivial affiché à l'utilisateur.
Pour conclure - l'exemple de code Microsoft dans le la documentation n’est pas toujours la meilleure.
First TRY ... CATCH: Un problème se produit dans la première commande, vous devez avoir un CATCH pour gérer la restauration. Deuxième essai ... CATCH: l'exception n'est pas si pertinente ici, mais vous ne voulez pas tout casser lorsque vous ne pouvez pas revenir en arrière. Certaines personnes rejettent l'exception "ex2" (je ne le fais pas!)