300 likes | 452 Views
Gestion de la concurrence avec Entity Framework. Développement d’application avec base de données Chapitre 23 Hugo St-Louis – Automne 2013. Plan de présentation. Introduction Qu’est-ce que le problème de la concurrence? Comment détecter un problème de concurrence
E N D
Gestion de la concurrence avec Entity Framework Développement d’application avec base de données Chapitre 23 Hugo St-Louis – Automne 2013
Plan de présentation • Introduction • Qu’est-ce que le problème de la concurrence? • Comment détecter un problème de concurrence • Comment gérer les problèmes de concurrences • Conclusion
Introduction • Les problèmes de concurrences sont des problèmes qui donnent des maux de tête aux programmeurs (mathématiciens) depuis la nuit des temps. • Problème des généraux byzantins • Etc.
Deux types de problèmes de concurrences • Les données que l’on tente de sauvegarder ont déjà été sauvegardées par quelqu’un d’autre. • Quelle version prend-on? Est-ce qu’on prend la version serveur ou la version client? • Les données qu’on tente de modifier n’existent plus dans la base de données. • On crée un nouvel enregistrement ou on ne fait rien?
Deux approches pour régler les problèmes de concurrences • L’approche Pessimiste: lors de la modification d’un enregistrement, cet enregistrement est barré(locked) pour éviter les problèmes de modifications concurrentes. Plusieurs bases de données fonctionnent sous ce principe…mais pas MS SQL. Dans ce cas, il faut développer cette fonctionnalité. • Problème: parfois les enregistrements restent barrés lors de panne ou autre problème inattendus. • L’approche Optimiste: c’est au développeur de gérer la gestion des mises à jour en fonction du « business logic ». • Cette approche est privilégiée avec l’entité Framework qui fournira des outils pour cette approche.
Quelques options de gestion optimiste • Qu’est-ce qu’on fait? • On prend la version client en tout temps. • On prend la version serveur en tout temps. • Comment on le fait? • On sauvegarde un champ de version d’enregistrement et on agit en conséquence? • On vérifie spécifiquement si l’ancienne version client des champs modifiés correspond à la version des champs sur le serveur.
Comment identifier les mises à jour • Il est possible d’ajouter un nouveau champ à notre enregistrement qui correspondrait à notre numéro de version. • Soit qu’on gère nous même le numéro de version ou une date de modification. • Soit on utilise un champ calculé propre à MS SQL de type timestamp • Bien que ce type s’appelle timestamp, c’est un champ binaire qui correspond à un identifiant calculé pour chaque sauvegarde. • Si une erreur de concurrence survient, une OptimisticConcurrencyException sera levée.
Comment identifier les mises à jour: Gestion par version • Page 663
Comment identifier les mises à jour: Gestion par version • Ensuite, il faut modifier la propriété Concurrency Mode à Fixed. Cette propriété permet de définir quel(s) champ(s) sera(ont) utilisé(s) pour valider les erreurs de concurrences. • De cette façon, le SaveChanges() vérifiera la version avant de faire une mise à jour. • En cas d’erreur, une OptimisticConcurrencyExceptionsera levée.
Comment identifier les mises à jour: Gestion par version • Faire un exemple.
Gestion optimiste de la concurrence avec l’Entité Framework et les procédures stockées • Si l’on utilise des procédures stockées, il est possible de vérifier automatiquement si la version précédente sur le serveur est identique à celle sur le client. Par contre, nous devrons modifier les procédures stockées pour inclure la RowVersion. • Il faut cocher l’option Utiliser la valeur originale. • Dans ce cas, les erreurs levées seront de type System.Data.Entity.Infrastructure.DbUpdateConcurrencyException
Gestion optimiste de la concurrence avec l’Entité Framework et les procédures stockées
Gestion optimiste de la concurrence avec l’Entité Framework et les procédures stockées
Gestion optimiste de la concurrence avec l’Entité Framework et les procédures stockées • Voir l’exemple
Gestion des erreurs de concurrence • Maintenant que nous avons vu comment identifier les erreurs de concurrence, il faut gérer ces erreurs. • Deux choix • Soit on force la sauvegarde de la version du client sur le serveur • Soit on rafraichit les données du client à partir du serveur
ObjectContext.Refresh • ObjectContext.Refreshpermet de rafraichir le contexte à partir de la base de données. • La méthode Refresh peut faire un rafraichissement des donnéessoitdans un scénarioClientWins ou un scénario StoreWins. • Si le scénarioest de type ClientWins, alors une requête sera envoyée à la base de données pour mettre à jour les «Originals Values » du contexte avec celle du serveur. Par conséquent, il sera possible de faire un SaveChanges() sans qu’une Exception de concurrence soit levée. • Si le scénarioest de type StoreWins, alors une requête sera envoyée à la base de données pour mettre à jour les «Originals Values » ET les « Current Values » du contexte avec celle du serveur. Par conséquent, les nouvelles valeurs seront écrasées.
ObjectContext.Refresh • ObjectContext.Refreshpermet de rafraichir le contexte à partir de la base de données. • La méthode Refresh peut faire un rafraichissement des donnéessoitdans un scénarioClientWins ou un scénario StoreWins. • Si le scénarioest de type ClientWins, alors une requête sera envoyée à la base de données pour mettre à jour les «Originals Values » du contexte avec celle du serveur. Par conséquent, il sera possible de faire un SaveChanges() sans qu’une Exception de concurrence soit levée. • Si le scénarioest de type StoreWins, alors une requête sera envoyée à la base de données pour mettre à jour les «Originals Values » ET les « Current Values » du contexte avec celle du serveur. Par conséquent, les nouvelles valeurs seront écrasées.
Forcer la sauvegarde de la version du client sur le serveur • On essaie de faire une sauvegarde. • Si une erreur est lancée, alors faire un rafraichissement des données originales du client à partir de celle du serveur. • Réessayer de sauvegarder tant qu’une erreur n’est pas lancée.
Forcer la sauvegarde de la version du serveur sur le client • On essaie de faire une sauvegarde. • Si une erreur est lancée, alors faire un rafraichissement des données originales du client et actuelles du client à partir de celle du serveur.
Forcer la sauvegarde de la version du serveur sur le client .
Attention! • Le context.Refresh() ne rafraichit pas les entités reliées. Vous devrez donc spécifier au Refresh si vous voulez qu’il rafraichisse un élément en particulier
Mise à jour d’une collection • Il est important de bien comprendre le processus de gestion d’erreurs. • Si vous exécutez un SaveChanges sur plusieurs enregistrements et qu’une exception est levée pour un enregistrement, il y aura un ROLLBACK sur tous les enregistrements sauvegardés dans cette transaction. NOTE: Le livre propose de surcharger la méthode SaveChanges et de l’appeler récursivement en cas d’exception. Jusqu’à preuve du contraire, la méthode itérative est toujours à privilégier sur la méthode récursive…
Conclusion • Nous avons vu les façons d’identifier les erreurs de concurrences avec des versions d’enregistrement. • Nous avons vu deux méthodes de gestions des erreurs de concurrences (ClientWins et StoreWins ). • Maintenant, à vous jouer dans le travail pratique #4.
Bibliographie • Lerman, J. (2010). ProgrammingEntity Framework, 2nd Edition.O'Reilly Media. Chapitre 23
Période de questions • Est-ce que vous avez des questions