Question

Je dois envoyer un e-mail, écrire dans un fichier, et d'appeler un service Web. Pour assurer la cohérence, toutes les étapes doivent se produire. Si une étape génère une exception ou d'erreurs, toutes les étapes doivent être annulées.

Avant que je vais rouler mon propre moteur objet ACID, sont-il des modèles communément acceptées pour la mise en œuvre sémantique ACID au niveau de l'objet?

Mieux encore, sont-il des bibliothèques existantes que je peux utiliser pour la la plate-forme .NET?

Modifier Je sais que l'envoi d'un e-mail ne peut pas être annulée, mais à défaut de se connecter au serveur SMTP est la cause de tuer toute l'opération. De plus, je voudrais que ce soit extensible pour des actions futures.

Était-ce utile?

La solution

La dernière fois que je voyais quelque chose comme cela était il y a plusieurs années. Le peu que je rappelle à ce sujet est qu'il a utilisé le modèle de commande et le stockage de chaque objet de commande dans une file d'attente. Je pense qu'il était une pile LIFO.

Donc, si la « transaction » a échoué, le moteur serait crèveront un objet de commande, annuler la commande, puis détruire l'objet de commande. Répétez jusqu'à ce que la pile était vide. La pile se est effacée si la « transaction » a réussi.

Malheureusement, je ne me souviens pas plus que cela.

CSLA.NET implémente une pile undo similaire. C'est le seul exemple avec le code que je peux penser du haut de ma tête.

Autres conseils

Windows Workflow Foundation a un concept de de compensation (en utilisant Composite activité) lorsque la sémantique ACID peut-être pas, il a appropriate..Off cours de soutien pour les transactions ACID ainsi.

  

Une bonne question est pourquoi embêter avec   compensation? Est-ce pas un grand ACID   transaction avec annulation automatique   tout aussi bien? Une transaction ACID est   le plus approprié lorsque les opérations se déroulent   au sein de la même base de données ou dans le   même système d'information. C'est aussi   le plus approprié lorsque la fin des opérations   rapidement. Lorsque différentes entreprises et   les services sont impliqués, la définition de la   processus en termes de la sémantique ACIDE   est souvent difficile. Pour que ce soit   isolé et durable, vous devez garder   toutes les ressources de différentes entreprises   verrouillé pendant toute la durée de la tâche.   Ceci est souvent déraisonnable,   surtout si la tâche est longue. Pour ça   être cohérent et atomique, vous avez besoin   ad hoc Code de compensation.

La technique la plus simple sans compter en grande partie sur une bibliothèque externe est prévalence . Régulièrement checkpoint à l'aide sérialisation pour prendre un instantané de votre état, puis maintenir un Journal par sérialisation assez d'informations sur toutes les opérations de côté effectful contre vos données pour répéter plus tard. Si quelque chose explose, recharger le point de contrôle le plus récent, puis appliquez tous les dossiers de revues écrits après ce point.

Pour quelque chose de plus sophistiqué, essayez logiciel mémoire transactionnelle. Il est peut-être un peu maladroit de mettre en œuvre dans les langues actuelles, mais est assez puissant et peut vous donner quelques techniques supplémentaires d'accès concurrentiel ainsi.

Pour les opérations irréversibles comme l'accès à un service Web ou en envoyant un e-mail, vous devez utiliser opérations de compensation : faire un autre appel de service Web pour annuler ou mettre à jour les résultats de la précédente, ou peut-être envoyer un e-mail informant le destinataire que les choses ne fonctionnent pas comme prévu

.

Puisque vous ne pouvez pas non envoyer un e-mail, et il est relativement peu coûteux d'écrire un fichier, je venais de faire les choses dans le bon ordre:

  1. Essayez d'écrire le fichier / écrire le fichier. Si unssuccessful, arrêtez, sinon continuer à:
  2. Appelez le service Web. En cas d'échec, supprimez le fichier et arrêter, sinon continuer à:
  3. Envoyer email - email est asynchrone de toute façon, vous sauriez jamais vraiment si elle a été envoyée ou non, puisque la plupart des serveurs de messagerie sont configurés pour une nouvelle tentative pour quelques jours si une erreur se produit et vous ne recevez jamais un accusé de réception que le courrier électronique est passé par même si elle n'a avec succès.

Une idée est d'utiliser JMS comme le « moteur » et vous pouvez utiliser les transactions JMS (qui peuvent se joindre à des transactions existantes par exemple de transaction DB). Cela commence à se diriger vers une architecture événementielle-async qui est probablement une bonne chose à moins que nous parlons des applications simples -. Dans ce cas, vous n'avez pas besoin probablement se poser la question

Un exemple de cela serait simple création de compte. Pour cela, vous voulez conserver les informations de compte à la base de données et envoyer également à l'utilisateur un e-mail pour l'activation - mais vous voulez dans la même transaction pour des raisons évidentes

.

Vous ne devriez pas mettre le code de l'envoi de courrier électronique dans la transaction parce que même si vous pouvez envoyer l'e-mail - transaction db commit peut échouer pour une raison ou une autre. Vous ne devriez pas mettre aussi l'envoi d'email en dehors de la transaction (commit après) parce que l'envoi d'e-mail peut échouer conduisant à un compte orphelin.

Donc, pour utiliser JMS dans ce scénario - mettre le code envoi JMS dans la transaction DB et l'ont se joindre à cette transaction. Vous avez la garantie de livraison des messages. À l'autre bout avoir quelque chose de consommer la file d'attente l'envoi de courriels sur. En cas d'email envoyer l'échec, la meilleure option est de se connecter / déclencher une alerte - JMS roulera en arrière et remettre un message dans la file d'attente pour une consommation ultérieure. à-dire d'essayer Renvoyez e-mail une fois que vous avez tout va bien fixé quel que soit le problème.

La chose essentielle est - enregistrement DB est cohérent et le courrier électronique est envoyé par la suite

.

Deux pensées:

  • Jeffrey Hantin mentionne, de (STM) est assez doux. Jetez un oeil à la façon dont il est mis en œuvre / utilisé dans Clojure ; Rich Hickey vidéos sont impressionnants.
  • Un aspect important de la modèle de commande de la renommée GoF est "undoability". Une la mise en œuvre de ce qui pourrait se résumer à la proposition simple (mais néanmoins utile) par Robert C. Barth

En outre, un projet expérimental STM .NET a été récemment publié . Ce projet ajoute de la mémoire de transaction à C #. Il modifie en fait le CLR à l'appui.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top