Nous utilisons un bus de service Azure pour informer les abonnés lorsqu'une entité de notre application est passée à un certain État. À l'heure actuelle, nous faisons cela juste après avoir appelé dbcontext.savechangeSasync (): p>
Le problème que j'ai, c'est ceci: dites que dbcontext.savechangeSasync () passe bien, mais pour une raison quelconque de l'appel à topicclient.Sendasync () jette une exception. Maintenant, les abonnés de ce sujet ne seront pas au courant de la modification de l'état de l'entité. P>
J'ai essayé d'utiliser des transactionsCope, mais cela ne fonctionne pas car, comme je l'ai rassemblé, Azure n'utilise pas le DTC. P>
(Je pourrais changer l'ordre des 2 étapes ci-dessus, mais si le message envoie une amende et que la sauvegarde échoue, le message contient des données FONGUS.) P>
Quelqu'un a-t-il des suggestions sur la manière de gérer ce problème? Il semble que celui qui devrait être commun, mais je ne trouve rien en ligne. Si quelqu'un pouvait me diriger dans la bonne direction, je l'apprécierais. P>
Merci d'avance. P> dbcontext.savechangeSasync () code> p> li>
topicclient.sendasync (Somemessage) code> p> li>
ol>
3 Réponses :
Vous pouvez implémenter le modèle appelé File d'attente de message empoisonnée ou Quue de lettre morte . Il existe d'autres synonymes connus tels que L'idée est d'essayer une opération et si elle ne réussit pas, mettez de la métainformation dans une file d'attente et de réessayer cette opération plus tard. Dans votre cas, après Bien sûr, vous pouvez dédier la file d'attente mentionnée uniquement pour les appels défaillants de Testez la file d'attente Code>. P>
dbcontext.savechangeSasync () code> est appelé, vous pouvez mettre toutes les informations nécessaires dans une file d'attente code> durable code> et avoir un gestionnaire qui traitera cette file d'attente et en quelque sorte de
processMessage () code> Vous pouvez gérer des appels de
TopicClient.Sendasync (Somemessage) Code>.
Par exemple, si l'appel au service de service ne réussit pas, vous pouvez retourner l'élément de la file d'attente dans la file d'attente pour le traitement ultérieur. P>
TopicClient.Sendasync (SOMEMESSAGE) CODE>, qui peut réduire considérablement sa taille. L'ordre de fonctionnement est insignifiant, car vous pouvez mettre n'importe quelle métainformation, ce qui permet de faire appeler
topicClient.sendasync (SOMEMESSAGE) code> Tout d'abord, puis essayez de mettre à jour la base de données. P>
Pas une réponse directe au problème à laquelle vous êtes confronté, mais je vais partager la manière dont nous avons résolu un problème similaire dans l'une de nos applications où nous avons dû écrire des données pour séparer les tableaux de stockage de table Azure. Parce que nous écrivions des données pour séparer les tableaux, nous ne pouvions pas utiliser la fonctionnalité de transaction par lots d'entité disponible dans le stockage de table Azure. P>
La façon dont nous avons résolu ce problème consiste à mettre en œuvre quelque chose de similaire à Ce que nous faisons est au lieu d'effectuer des données d'enregistrement directement dans les tableaux (ce qui signifie que de multiples demandes de réseau pouvaient échouer), nous envoyons les données à enregistrer dans une file d'attente (la file d'attente de stockage). Si nous sommes en mesure de sauvegarder les données de la file d'attente, cela signifie que les données seront éventuellement disponibles. P>
Ensuite, nous avons écrit une fonction déclenchée de la file d'attente Azure. Dans cette fonction, nous économisons des données dans les tableaux où nous devrions économiser. Une fois que toutes les opérations réussissent, le message est automatiquement supprimé par la fonction Runtime. Si toute partie de l'opération échoue, le message sera envoyé à la file d'attente et sera à nouveau détresse. P>
Maintenant, une chose importante à comprendre est que ces méthodes de sauvegarde doivent être idempotentes. Disons que nous écrivons dans 3 tables et une opération d'écriture pour la 1ère table réussit, mais l'opération d'écriture pour la 2e table échoue. La prochaine fois que la fonction est invoquée, elle tentera d'écrire à la 1ère table et le code doit pouvoir gérer ce gracieusement. P> Modèle de consistance éventuelle code>. P>
Merci beaucoup. Je vais regarder dans ça.
Comme vous avez décrit, l'ordre des opérations n'aura pas d'importance car il n'ya aucune transaction qui se chevauche entre les deux services, la base de données et le service de messagerie. Si le magasin de données que vous utilisez des opérations de support (par exemple, Azure SQL Server), vous pouvez vous éloigner sans utiliser de commettre deux phases et regarder dans la mise en œuvre du modèle de boîte d'envoi . p>
NSERVICEBUS fournit le modèle en tant que Fonction . Vous pouvez télécharger la boîte d'envoi échantillon qui montre comment l'utiliser avec RabbitMQ. Le transport peut être remplacé par Transport de bus de service Azure pour répondre à votre exigence. p>
Divulgation: je contribue à NSERVICEBUS. P>
Merci beaucoup. Je vais vérifier cela.
J'ai fini par aller avec le modèle de boîte d'envoi transactionnel, comme vous l'avez suggéré, avec une implémentation ihostedService pour surveiller la table des boîtes d'envoi. Merci pour la suggestion et désolé, il m'a fallu si longtemps pour que je réponde.
Heureux d'entendre c'était ce que vous cherchez. Et toujours génial d'entendre une confirmation, merci. 🙂