Gestion des échecs de validation de transaction
Remarque
EF6.1 et versions ultérieures uniquement : Les fonctionnalités, les API et autres caractéristiques décrites dans cette page ont été intégrées dans Entity Framework 6.1. Si vous utilisez une version antérieure, certaines ou toutes les informations ne s’appliquent pas.
La version 6.1comprend une nouvelle fonctionnalité de résilience de connexion pour EF : la possibilité de détection et de récupération automatique lorsque des défaillances de connexion temporaires affectent la confirmation de validation de transaction. Les détails complets du scénario sont décrits dans le billet de blog Connectivité SQL Database et problème d’Idempotence. En résumé, lorsqu’une exception est levée au cours d’une validation de transaction, le scénario prévoit deux causes possibles :
- Échec de validation de transaction sur le serveur
- La validation de transaction a réussi sur le serveur, mais un problème de connectivité a empêché la notification de réussite de parvenir au client
Lorsque la première situation se produit, l’application ou l’utilisateur peut renouveler l’opération, mais lorsque la deuxième situation se produit, les nouvelles tentatives doivent être évitées et l’application peut restaurer automatiquement les données. Le défi est que sans la possibilité de détecter la raison réelle pour laquelle une exception a été levée pendant la validation, l’application ne peut pas choisir le plan d’actions approprié. La nouvelle fonctionnalité de la version 6.1 permet à EF de procéder à une double vérification de la base de données si la transaction a réussi et d’exécuter le bonne chaîne d’actions de manière transparente.
Utilisation de la fonctionnalité
Pour activer la fonction dont vous avez besoin, incluez un appel à SetTransactionHandler dans le constructeur de votre DbConfiguration. Si vous n’êtes pas familiarisé avec DbConfiguration, consultez Configuration basée sur le code. Cette fonctionnalité peut être utilisée de façon combinée avec les nouvelles tentatives automatiques que nous avons intégrées dans EF6, ce qui aide dans le cas où la transaction n’a pas réellement échoué sur le serveur en raison d’une défaillance temporaire :
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy());
}
}
Suivi de transactions
Lorsque la fonctionnalité est activée dans EF, une nouvelle table appelée __Transactions est ajoutée automatiquement à la base de données. Une nouvelle ligne est insérée dans cette table chaque fois qu’une transaction est créée par EF, et l’existence de cette ligne est vérifiée si une défaillance de transaction se produit pendant la validation.
Bien que EF s’efforce de réduire au mieux le nombre de lignes qui ne sont plus nécessaires dans la table, celle-ci peut s’agrandir si l’application se ferme prématurément. Pour cette raison, vous devrez peut-être vider la table manuellement dans certains cas.
Gestion des échecs de validation avec les versions antérieures
Avant EF 6.1, il n’y avait aucun processus permettant de gérer les échecs de validation dans le produit EF. Pour traiter ces défaillances, il existe plusieurs solutions qui peuvent être appliquées aux versions précédentes d’EF6 :
Option 1 : ne rien faire
La probabilité d’un échec de connexion lors de la validation des transactions est faible. Il peut donc être acceptable que votre application échoue simplement si le cas se produit réellement.
Option 2 : utiliser la base de données pour réinitialiser l’état
- Ignorez le DbContext actuel
- Créez un DbContext et restaurez l’état de votre application à partir de la base de données
- Informez l’utilisateur que la dernière opération n’a peut-être pas été effectuée avec succès
Option 3 : suivre la transaction manuellement
- Ajoutez une table sans suivi à la base de données utilisée pour suivre l’état des transactions.
- Insérez une ligne dans cette table au début de chaque transaction.
- Si la connexion échoue pendant la validation, vérifiez que la ligne correspondante apparaît dans la base de données.
- Si la ligne est présente, poursuivez normalement, car cela signifie que la transaction a été validée avec succès
- Si la ligne est absente, utilisez une stratégie d’exécution pour une nouvelle tentative de l’opération actuelle.
- Si la validation est réussie, supprimez la ligne correspondante pour éviter l’extension de la table.
Ce billet de blog contient des exemples de code pour effectuer ceci sur SQL Azure.