2010-06-10 7 views
9

Disons que vous avez une application connectant 3 systèmes externes différents. Vous devez mettre à jour quelque chose dans tous les 3. En cas d'échec, vous devez annuler les opérations. Ce n'est pas une chose difficile à implémenter, mais dites que l'opération 3 échoue, et lors de la restauration, l'annulation de l'opération 1 échoue! Maintenant, le premier système externe est dans un état invalide ...Opérations atomiques sur plusieurs systèmes externes sans transaction

Je pense qu'une solution possible est de fermer l'application et de forcer une correction manuelle du système externe, mais encore une fois ... Il pourrait déjà avoir utilisé cette information (et peut-être c'est pourquoi il a échoué), ou nous pourrions ne pas avoir un accès suffisant. Ou ce n'est peut-être même pas un bon moyen de revenir en arrière!

Y a-t-il de bons moyens de traiter de tels cas?

EDIT: Quelques détails d'application ..

Il est une application web multi-utilisateur. La plupart du travail est effectué avec des tâches planifiées (via Quartz.Net), donc la plupart des opérations sont exécutées dans son propre thread. Certaines actions utilisateur doivent déclencher des tâches qui mettent à jour plusieurs systèmes. Les systèmes externes sont quelque peu instables.

Je pensais à changer l'application à utiliser l'unité de commande et de modèle de travail

+0

Les systèmes externes sont-ils corrigés? Ou pouvez-vous les modifier? – bmargulies

Répondre

1

La validation en deux phases (2PC) pourrait convenir ici.

La première phase consiste à faire en sorte que les différentes bases de données acceptent d'aller de l'avant avec la validation. Dans votre exemple, la base de données 1 ne procédera pas à l'écriture jusqu'à ce qu'il soit certain que les trois bases de données ont signalé que la transaction sera possible. Cela se compare au processus que vous décrivez qui est une approche "optimiste" - La base de données 1 supposera que la transaction doit se poursuivre jusqu'à ce qu'elle apprenne le contraire, et soit obligée de revenir en arrière.

+0

Merci. C'est un peu ce que j'ai déjà en utilisant UnitOfWork avec Execute, Commit et Rollback qui stocke les commandes ayant CanProcess Do et Undo. – simendsjo

0

En fonction de la taille de l'application (utilisateur unique par rapport à l'entreprise), l'arrêt de l'application pourrait être une mauvaise idée. Tout d'abord, je suggère de sauvegarder l'état initial de l'information en cours de modification dans les 3 applications externes pour le stockage local à votre propre application. Cela signifie que vous pouvez au moins déterminer ce que l'état de restauration est supposé être en cas de panne de votre application/échec de la restauration/etc. Une fois la transaction validée, vous pouvez ensuite supprimer ces données. Que faire lorsque l'une des opérations échoue dépend de la fonctionnalité des trois systèmes externes. Supposons que l'un de ces systèmes contient des données sur les employés. La fermeture de l'application simplement parce que l'adresse d'un employé est erronée en raison d'une transaction échouée est exagérée. Il est préférable de simplement vérifier le journal des transactions ayant échoué (c'est-à-dire le stockage local sur lequel vous avez sauvegardé les états initiaux des 3 applications externes) chaque fois que vous accédez aux données d'un employé. Si les données de cet employé sont marquées comme non valides, lancez une erreur indiquant que l'enregistrement est dans un état non valide et ne peut pas être récupéré.

Cependant, si le système externe entier est désorganisé par une transaction ayant échoué, alors oui - vous ne pouvez rien faire ici mais arrêter votre application jusqu'à ce que le problème soit résolu.

1

Souhaitez-vous expliquer plus en détail comment l'annulation de l'opération 1 pourrait échouer?

L'état auquel il vise est celui dans lequel il a été précédemment, donc il devrait être logiquement cohérent.Il peut y avoir des problèmes transitoires comme l'échec du réseau, mais il se peut que le meilleur moyen d'y remédier est de réessayer jusqu'à ce que les problèmes disparaissent. Si le problème est que les transactions suivantes ont verrouillé ou modifié les données entre-temps, vous avez un problème beaucoup plus important: vos transactions ne sont pas atomiques et leur annulation peut rendre invalide la sortie d'autres transactions.

0

La réponse d'Oddthinking est une bonne, mais limitée parce qu'il est très difficile de réellement faire un 2PC. Cela a été connu dans la communauté informatique distribuée depuis un certain temps, bien que beaucoup de gens font de leur mieux pour l'ignorer.

Si vous êtes intéressé à approfondir dans ce domaine, le Paxos consensus algorithm est un bon point de départ. Et sachez qu'il s'agit d'un problème étonnamment difficile, précisément à cause des problèmes auxquels vous faites allusion et du fait qu'il est en réalité impossible de construire un système de messagerie vraiment fiable capable de délivrer un message dans un laps de temps limité. (Pour comprendre pourquoi c'est vrai, considérez que someone with a backhoe pourrait effacer tous les liens de réseau entre les différentes parties communiquantes ...)

Je suspecte que le vrai problème est de concevoir l'architecture du système global et comment vous déployez les changements à travers lui ainsi qu'une perte de communication dans une zone n'est pas catastrophique. Cela peut ou peut ne pas être facile à faire, en fonction des détails exacts.

Questions connexes