2017-06-16 5 views
0

J'ai la boucle de oledb de base suivante:C# Dois-je placer la transaction Sql/OleDb.Commit() en dehors d'une boucle for?

using (OleDbConnection conn = new OleDbConnection(Con)) 
{ 
    using (OleDbCommand cmd = new OleDbCommand()) 
    { 
     for loop 
     { 
     cmd.Connection = conn; 
     conn.Open(); 
     transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted); 
     cmd.CommandText = "row by row insert" 
     cmd.Some parameters, then ExecuteNonQuery 
     transaction.Commit(); 
     } 
    } 
} 

Cependant, je ne suis pas certain si je devrais plaçant le Commit dans la boucle après l'exécution de la commande. Dois-je le placer après tout est dit et fait? Décrivant le using serait un try catch contenant une restauration dans le catch. Donc, je devine si je veux être en mesure de revenir en arrière sur tous mes changements, je veux que la boucle fonctionne complètement, puis le commettre?

Je viens également d'apprendre à propos de TransactionScope s qui décrivent le contexte SQL dans un usage, donc j'aimerais savoir comment cela s'applique à cela aussi.

+1

Selon vos besoins. Est-ce que toutes les commandes 'INSERT' devraient être réinitialisées en cas d'échec? – jAC

+0

Oui, je suppose que c'est vrai. Donc, si c'est dans la boucle, le plus la capture reculera serait la dernière rangée ajoutée? En outre, j'essaye d'employer le TransactionScope, j'ai ajouté la référence et tel, je suppose que ceci fonctionnera avec n'importe quelle base de données agnostique de la plate-forme? Parce que je ne vois nulle part pour le définir. @JanesAbouChleih – Arvayne

+1

Exactement, votre code maintenant, ne ferait que réinitialiser la transaction pour le dernier 'INSERT'. Si vous le placez en dehors de la boucle (avec conn.BeginTransaction (IsolationLevel.ReadCommitted), bien sûr), toutes les commandes 'INSERT' gérées dans cette transaction/for loop seront réinitialisées. Mais pour le moment, il manque encore une gestion des exceptions lorsque vous manipulez 'transaction.Rollback()'. €: Comme l'a déjà indiqué @Mike Nakis, cela a également un impact énorme sur les performances de votre db, puisque toutes les transactions sont enregistrées. Par conséquent, moins de transactions = performances plus rapides. Je n'ai pas compris la question 'TransactionScope'. – jAC

Répondre

2

Vous ne pouvez pas déplacer l'appel Commit() en dehors de la boucle lorsque l'appel BeginTransaction() se trouve dans la boucle. Les deux resteront dans la boucle, ou les deux iront en dehors de la boucle.

Alors, votre question devrait être: « devrait-je effectuer une transaction par itération de ma boucle, ou devrais-je commencer une transaction, faire ma boucle, puis valider la transaction? » Eh bien, la seule raison de faire une transaction par itération serait le scénario très peu probable où vous voudriez que toutes les insertions non défaillantes soient validées même si certaines d'entre elles échouent. (Dans ce cas, vous devrez également faire une gestion des exceptions.)

Si vous ne disposez pas d'une telle exigence, et si vous ne me dérangerait pas d'un ordre de grandeur amélioration de la performance, alors vous feriez mieux de commencer une transaction, faites votre boucle, puis fermez votre transaction.