Il y a eu plusieurs discussions sur les transactions distribuées(Cohérence finale des messages fiables Transactions distribuées - TCC Transactions distribuées - 2PC、3PC),Mais il n'y a pas eu de combat réel.Alors, dans cet article, nous allons vous montrer comment .NET Réaliser une transaction distribuée basée sur un message fiable dans un environnement.Les processus de transaction distribués basés sur des messages fiables sont encore assez clairs,Mais il est encore plus difficile d'implémenter un par un avec le Code.L'analyse montre que le point clé de cette transaction est d'être en avance sur la vraie logique d'entreprise、Insérer le processus correspondant après.Il est clair que ce processus peut passer par AOP Technologie pour simplifier le fonctionnement.Et voilà. AgileDT .AgileDT Utiliser Natasha Générer dynamiquement la classe proxy au démarrage,Pour compléter les opérations avec la section message pour vous,Les utilisateurs n'ont qu'à se soucier de la logique opérationnelle de base.

https://github.com/kklldog/AgileDT Open source n'est pas facile, Tout le monde!

Rétrospective

Article précédent(Cohérence finale des messages fiables ) Nous Détaillons les transactions distribuées basées sur des messages fiables .Pour une meilleure compréhension AgileDT Code, Il est encore nécessaire d'examiner brièvement .



Le processus global du plan peut être divisé en étapes comme suit::

  1. L'initiateur envoie un message au service de messagerie fiable avant le début d'une véritable entreprise“À confirmer”Message de
  2. Le Service de messagerie fiable maintient le message dans la base de données après avoir reçu le message à confirmer
  3. Si l'opération ci - dessus est réussie, l'initiateur commence une véritable entreprise,Abandonner l'exécution de l'entreprise en cas d'échec
  4. Envoyer si l'opération est réussie“Confirmation”Message au service de messagerie fiable,Envoyer si l'exécution échoue“Annulation”Service de messagerie fiable.
  5. Si le Service de messagerie fiable reçoit“Confirmation”Le message met à jour l'état de l'enregistrement du message dans la base de données à“À envoyer”,Si le message reçu est“Annulation”L'état du message de mise à jour est“Annulé”
  6. Si la base de données mise à jour à l'étape précédente est“À envoyer”,Ça va commencer.MQEnvoyer un message,Et changer l'état des enregistrements de messages dans la base de données à“Envoyé”
  7. Avancez.MQAprès la livraison réussie du message,MQEnvoie un message à la partie passive.
  8. La partie passive commence à traiter les affaires après avoir reçu le message
  9. Si l'entreprise est traitée avec succès,Alors la paire passiveMQEn coursACKRéponse,Ce message sera envoyé à partir deMQRetrait interne
  10. Si l'entreprise est traitée avec succès,Envoyer“Terminé”Message au service de messagerie fiable
  11. Reçu par le Service de messagerie fiable“Terminé”Mise à jour de l'enregistrement des messages de la base de données après le message non“Terminé”

Arrête tes conneries., Voyons comment utiliser AgileDT Pour réaliser rapidement une transaction distribuée basée sur un message fiable .

Ci - dessous, nous montrons également le scénario classique de commande pour compléter les points donnés aux membres. .

Utiliser AgileDT

Composante dépendante

  • mysql
  • rabbitmq

Actuellement pris en charge mysql Base de données, Mais la composante accès aux données utilise freesql Il est donc facile de prendre en charge d'autres bases de données par la suite. . Les services de messagerie fiables actuellement utilisés par le cadre sont: rabbitmq .

Exécuter le serveur

Créer une nouvelle base de données et une nouvelle table dans le Service

// crate event_message table on mysql
create table if not exists event_message
(
event_id varchar(36) not null
primary key,
biz_msg varchar(4000) null,
status enum('Prepare', 'Done', 'WaitSend', 'Sent', 'Finish', 'Cancel') not null,
create_time datetime(3) null,
event_name varchar(255) null
);

Utiliserdocker-composeExécuter le serveur

version: "3"  # optional since v1.27.0
services:
agile_dt:
image: "kklldog/agile_dt"
ports:
- "5000:5000"
environment:
- db:provider=mysql
- db:conn= Database=agile_dt;Data Source=192.168.0.115;User Id=root;Password=mdsd;port=3306
- mq:userName=admin
- mq:password=123456
- mq:host=192.168.0.115
- mq:port=5672

Installer un client

Doit être installé à la fois sur le côté actif et sur le côté passif AgileDTBibliothèque client pour

Install-Package AgileDT.Client

Méthode d'utilisation de l'initiateur

  1. Ajouter une table de messages de transaction à la base de données des entreprises
// crate event_message table on mysql
create table if not exists event_message
(
event_id varchar(36) not null
primary key,
biz_msg varchar(4000) null,
status enum('Prepare', 'Done', 'WaitSend', 'Sent', 'Finish', 'Cancel') not null,
create_time datetime(3) null,
event_name varchar(255) null
);
  1. Modifier le profil
Inappsettings.json Le fichier ajoute le noeud suivant :
"agiledt": {
"server": "http://localhost:5000",
"db": {
"provider": "mysql",
"conn": "Database=agile_order;Data Source=192.168.0.125;User Id=dev;Password=dev@123f;port=13306"
//"conn": "Database=agile_order;Data Source=192.168.0.115;User Id=root;Password=mdsd;port=3306"
},
"mq": {
"host": "192.168.0.125",
//"host": "192.168.0.115",
"userName": "admin",
"password": "123456",
"port": 5672
}
}
  1. Injection AgileDT Services à la clientèle
       public void ConfigureServices(IServiceCollection services)
{
services.AddAgileDT();
...
}
  1. RéalisationIEventServiceMéthodes

    La classe qui gère la logique opérationnelle de l'initiative doit être mise en œuvre IEventServiceInterface, Et marquer cette méthode est la vraie méthode d'affaires .AgileDT Ces types sont scannés au démarrage ,Et utiliserAOP Classe d'agent de génération de technologie , Insérer la logique correspondante avant et après la méthode d'affaires pour communiquer avec un service de messagerie fiable .

    Quelques points à noter ici :
  • RéalisationIEventServiceInterface
  • UtiliserDtEventBizMethod Annotation Tag Business entry Method
  • UtiliserDtEventName Nom de la méthode annotée pour marquer la transaction , Utiliser le nom de la classe s'il n'est pas marqué

Attention!: Les méthodes d'affaires doivent éventuellement utiliser des transactions pour synchroniser la modification d'une table de messages statusLe champ estdoneStatut, Ce cadre opérationnel ne vous aidera pas à le mettre en œuvre.

Attention!: Si la méthode d'affaires échoue, lancez - la. Exception, L'exécution est considérée comme réussie si le cadre d'exception n'est pas lancé.

 public interface IAddOrderService:IEventService
{
bool AddOrder(Order order);
} [DtEventName("orderservice.order_added")]
public class AddOrderService : IAddOrderService
{
private readonly ILogger<AddOrderService> _logger; public AddOrderService(ILogger<AddOrderService> logger)
{
_logger = logger;
} public string EventId {
get;
set;
} [DtEventBizMethod]
public virtual bool AddOrder(Order order)
{
var ret = false; //3. Écris. Order Suivez - moi. Modifier event L'état de doit être écrit dans la même transaction
FreeSQL.Instance.Ado.Transaction(() =>
{
order.EventId = EventId;// Ajouter un nouveau formulaire de commande eventidChamp,FaireorderSuivez - moi.event_message Tableaux liés
var ret0 = FreeSQL.Instance.Insert(order).ExecuteAffrows();
var ret1 = FreeSQL.Instance.Update<OrderService.Data.entities.EventMessage>()
.Set(x => x.Status, MessageStatus.Done)
.Where(x => x.EventId == EventId)
.ExecuteAffrows(); ret = ret0 > 0 && ret1 > 0;
}); return ret; } /// <summary>
/// Construire le contenu du message nécessaire au traitement ultérieur des affaires
/// </summary>
/// <returns></returns>
public string GetBizMsg()
{
// Ici, vous pouvez construire le passage à MQ Contenu du message d'affaires pour , Comme le numéro d'ordre de livraison. , Utilisé par les parties passives suivantes lors du traitement des affaires
var order = FreeSQL.Instance.Select<Order>().Where(x => x.EventId == EventId).First();
return order?.Id;
} }

On y arrive. IAddOrderService Après l'interface, Vous pouvez l'utiliser comme d'habitude IAddOrderService Pour injecter des classes d'implémentation .Comme dans Controller Le constructeur de .Parce que AgileDT Vous serez automatiquement enregistré au démarrage .

Attention!:IAddOrderService Et le cycle de vie de la classe d'implémentation est Scoped .

Méthode d'utilisation passive

  1. Créer une table dans la base de données de l'entreprise ou ajouter des champs à la table de l'entreprise

    Il n'est pas nécessaire de construire une table pour un passif . Mais il faut au moins un endroit pour le stocker. event_idInformations sur, Le plus simple est d'ajouter directement au tableau principal de l'entreprise event_idChamp.
  2. Modifier le profil
Inappsettings.json Le fichier ajoute le noeud suivant :
"agiledt": {
"server": "http://localhost:5000",
"db": {
"provider": "mysql",
"conn": "Database=agile_order;Data Source=192.168.0.125;User Id=dev;Password=dev@123f;port=13306"
//"conn": "Database=agile_order;Data Source=192.168.0.115;User Id=root;Password=mdsd;port=3306"
},
"mq": {
"host": "192.168.0.125",
//"host": "192.168.0.115",
"userName": "admin",
"password": "123456",
"port": 5672
}
}
  1. InjectionAgileDTServices
       public void ConfigureServices(IServiceCollection services)
{
services.AddAgileDT();
...
}
  1. RéalisationIEventMessageHandlerInterface

    La partie passive doit recevoir MQ Message envoyé , Ces classes de traitement doivent être mises en œuvre IEventMessageHandlerInterface.AgileDT Scanne ces classes au démarrage ,Et suivreMQÉtablir une relation de liaison.
  • Doit être utilisé ici DtEventName Annotation Tag nom de l'événement à traiter
  • Reveive La méthode doit être invisible.
    public interface IOrderAddedMessageHandler: IEventMessageHandler
{
} [DtEventName("orderservice.order_added")]
public class OrderAddedMessageHandler: IOrderAddedMessageHandler
{
static object _lock = new object(); public bool Receive(EventMessage message)
{
var bizMsg = message.BizMsg;
var eventId = message.EventId;
string orderId = bizMsg; lock (_lock)
{
var entity = FreeSQL.Instance.Select<PointHistory>().Where(x => x.EventId == eventId).First();
if (entity == null)
{
var ret = FreeSQL.Instance.Insert(new PointHistory
{
Id = Guid.NewGuid().ToString(),
EventId = message.EventId,
OrderId = orderId,
Points = 20,
CreateTime = DateTime.Now
}).ExecuteAffrows(); return ret > 0;
}
else
{
return true;
}
}
}
}

Résumé

Par la démonstration ci - dessus , Nous avons rapidement mis en œuvre un service de points gratuits pour les membres qui passent des commandes .Vous pouvez voir l'utilisation AgileDT Peut rapidement mettre en œuvre une transaction distribuée . Surtout après la mise en œuvre d'une transaction distribuée , C'est très simple à mettre en œuvre. , Il suffit d'implémenter quelques interfaces .AgileDT Ça vient de commencer,J'espère que tout le monde soutiendra,Dodo ,Dodo PR .

https://github.com/kklldog/AgileDT

.Net Core with Microservices - Utiliser AgileDT Plus d'articles sur la mise en oeuvre rapide de transactions distribuées basées sur des messages fiables

  1. spring cloud+dotnet core Mise en place d'une architecture de micro - services :Découverte de services(2.)

    Préface L'article précédent ne portait en fait que sur l'enregistrement des services dans la gouvernance des services. , Comment les services sont - ils appelés entre eux? ?La manière traditionnelle,ServicesAAppeler le serviceB,Alors le serviceA Accès aux services B Adresse d'équilibrage de charge pour , Pointer vers le service par équilibrage de charge BAdresse réelle de, C'est déjà dit dans le dernier article. ...

  2. spring cloud+.net core Mise en place d'une architecture de micro - services :Découverte de services(2.)

    Préface L'article précédent ne portait en fait que sur l'enregistrement des services dans la gouvernance des services. , Comment les services sont - ils appelés entre eux? ?La manière traditionnelle,ServicesAAppeler le serviceB,Alors le serviceA Accès aux services B Adresse d'équilibrage de charge pour , Pointer vers le service par équilibrage de charge BAdresse réelle de, C'est déjà dit dans le dernier article. ...

  3. .Net Core with Microservices - Schéma

    La dernière fois que nous avons présenté brièvement ce qu'est un micro - service (.NET Core with Microservices - Qu'est - ce qu'un micro - service ). Le contexte du micro - service est introduit , Quelques concepts fondamentaux . Il y a des gars dans la section commentaires qui disent que ce n'est pas du tout un micro - service. .En raison de mes capacités limitées, Probablement aussi. ...

  4. Les mains vous apprennent à utiliserspring cloud+dotnet core Mise en place d'une architecture de micro - services :Gouvernance des services(-)

    Contexte L'entreprise a commencé à l'utiliser l'année dernière dotnet coreProjets de développement. L'architecture globale de l'entreprise utilise des micro - services , À cette époque, parce que la compréhension des micro - services n'était pas si profonde , Plus l'immaturité des différents composants , Il s'agit simplement de diviser les fonctions du projet au niveau opérationnel. ,Et à traversnginxGénération ...

  5. spring cloud+dotnet core Mise en place d'une architecture de micro - services :ApiPasserelle(Trois)

    Préface Fête nationale, Il n'y a pas eu de temps pour mettre à jour . D'après les questions des élèves du Groupe, , Nous vous recommandons fortement de vous familiariser avec spring cloud. Il y a des dieux purs en bas de l'article spring cloudSérie. Le dernier chapitre est terminé. , Parce que le service n'est pas exposé ,Bureau ...

  6. spring cloud+dotnet core Mise en place d'une architecture de micro - services :Centre de configuration(Quatre)

    Préface Il y a beaucoup de choses à configurer dans notre projet , Les services les plus courants URLAdresse, Ces adresses sont différentes pour différents environnements d'exécution , Qu'il s'agisse d'emballage ou de déploiement , Il faut être très prudent. . La configuration générale est stockée dans le fichier de configuration , Peu importe le petit changement de configuration , ...

  7. spring cloud+dotnet core Mise en place d'une architecture de micro - services : Centre de configuration suite (Cinq)

    Préface Le chapitre précédent est terminé. , Le client doit être redémarré après la mise à jour de la configuration pour prendre effet , Cela n'est pas souhaitable dans un scénario réel .Pour l'instantSteeltoe La surcharge configurée ne peut être initiée que par le client , Aucun gestionnaire d'implémentation n'écoute les événements de changement de serveur , Il n'y a donc pas de moyen d'y parvenir. ...

  8. spring cloud+dotnet core Mise en place d'une architecture de micro - services :ApiCertification autorisée(Six)

    Préface Cet article est trop long. , Parce que j'ai été trop occupé ces derniers temps. , Et cet article est très long. , Ça a pris du temps. , Désolé pour tout le monde. .D'accord.,Passez au sujet. Les projets actuels sont essentiellement séparés de l'avant et de l'arrière , Division frontale Web,Ios,Android..., L'arrière - plan est aussi basique ...

  9. spring cloud+.net core Mise en place d'une architecture de micro - services :Inscription au service(Un.)

    Contexte L'entreprise a commencé à l'utiliser l'année dernière dotnet coreProjets de développement. L'architecture globale de l'entreprise utilise des micro - services , À cette époque, parce que la compréhension des micro - services n'était pas si profonde , Plus l'immaturité des différents composants , Il s'agit simplement de diviser les fonctions du projet au niveau opérationnel. ,Et à traversnginxGénération ...

  10. spring cloud+.net core Mise en place d'une architecture de micro - services :ApiCertification autorisée(Six)

    Préface Cet article est trop long. , Parce que j'ai été trop occupé ces derniers temps. , Et cet article est très long. , Ça a pris du temps. , Désolé pour tout le monde. .D'accord.,Passez au sujet. Les projets actuels sont essentiellement séparés de l'avant et de l'arrière , Division frontale Web,Ios,Android..., L'arrière - plan est aussi basique ...

Recommandation aléatoire

  1. UtilisationQMPEtQEMU Plusieurs façons d'interagir avec la machine virtuelle

    QMPEst basé surJSON Format du Protocole de transport , Nous pouvons l'utiliser avec QEMU Les instances de la machine virtuelle interagissent ,Par exemple, une requête, Modifier l'état de la machine virtuelle , Obtenir des informations sur l'appareil, etc. . Voici quelques exemples de création QMP Et l'utilisation d'autres commandes de base : 1.Basé sur ...

  2. MySQL Requête avancée pour

    Requête avancée 1.Requête de connexion( Extension des colonnes ) La première formeselect * from Info,Nation # Produit cartésien select * from Info,Nation where Info.Nati ...

  3. C# Réaliser le transfert de fichiers Lan

    Les communications réseau passent généralement par SocketEn cours, Appelé mécanisme de communication de processus ,Souvent appelé"Socket",Utilisé pour décrireIPAdresse et Port,C'est la poignée d'une chaîne de communication. Apprends d'abord. socketJustification: socketPrincipes: ...

  4. Utiliserlogmnr Méthode de récupération supprimée par erreur Oracle Script de données pour

    Comme dit le proverbe:,Souvent en marchant près de la rivière, Où sont les chaussures mouillées? . En tant que programmeur qui travaille souvent avec des bases de données , Les données accidentellement effacées ou manipulées sont également inévitables. .Si ouiOracleBase de données, Voici un moyen de récupérer les données du Journal , Voici mon adresse ...

  5. Cent OSInstallationTL-WN725N 2.0 USBDrive

    TP LinkLes autorités n'ont pas fourniTL-WN725N 2.0DeLinuxTéléchargement du pilote, Ça m'a énervé. , J'ai essayé toutes sortes de méthodes. . En partie parce que la machine n'est pas encore connectée. , Certains pilotes n'ont pas été installés avec succès en raison du manque de dépendances . Et finalement gith ...

  6. PHPGratuitAPIAppelez,Utiliser(CURL)

    <?phpclass GetApiModel{// Accès à des tiers API // Obtenir des renseignements sur la carte d'identité //Retourjson /*{ "errNum": 0, "retMsg" ...

  7. InXAML Installer un auditeur d'événements pour l'arborescence des noeuds dans le Code

    Utilisez l'exemple de code de démonstration suivant ,Capable de découvrir, Nous pouvons spécifier les événements de routage à écouter pour n'importe quel noeud , Et cet événement de routage lui - même n'a peut - être rien à voir avec cet élément . <Window x:Class="Demo002.MainW ...

  8. [linux]ubuntu apt-get Impossible d'installer le logiciel

    1.Voir d'abord dns Configuration sudo vi /etc/resolv.conf nameserver 114.114.114.114 nameserver 8.8.8.8 2.Modifier apt-get Source ...

  9. linux Sauvegarde Documentation+sql

    sql 1 2 3 rm -f /bak/bak.sql mysqldump --databases nl -uroot -p413121 > /bak/bak.sql curl http:// ...

  10. JQ Ajouter un gestionnaire d'événements pour les éléments futurs —Délégation d'événements

    AvecDOM La complexité de la structure et Ajax Application de la technologie de script isodynamique , Avec plus d'éléments ajoutés dynamiquement ,Utilisation directeJQAjouterclick L'événement découvre que les éléments nouvellement ajoutés ne peuvent pas être directement sélectionnés , La méthode de délégation d'événements est nécessaire ici ,JQ Fournir à la délégation d'événements ...