Partager via


Gestion des transactions

Récepteurs traités

La main différence entre les récepteurs traités et les récepteurs non traduits est que les récepteurs traités créent et utilisent une transaction MSDTC explicite pour garantir l’atomicité entre leur source de données et la base de données MessageBox BizTalk Server. En général, les autres aspects de l'adaptateur sont les mêmes.

Notez que l'adaptateur de réception requête-réponse n'utilise une transaction que pour envoyer le message de requête original au moteur de messagerie. Une transaction différente est nécessaire pour la transmission de la réponse envoyée du moteur de messagerie à l'adaptateur. Cela est dû au fait que l'étendue de la première transaction va de l'adaptateur à la base de données MessageBox. Le message de requête suivant n'est pas envoyé à l'adaptateur depuis le moteur de messagerie avant que la transaction du message de requête original n'ait été validée.

Le diagramme d'interaction d'objets suivant présente l'interaction entre l'adaptateur et le moteur de messagerie pendant l'envoi transactionnel des messages entrants. Dans cet exemple, la série d'interactions suivante se produit :

  1. L'adaptateur reçoit un nouveau lot du moteur.

  2. L'adaptateur crée et retourne une nouvelle transaction MSDTC.

  3. L'adaptateur procède à une lecture destructive depuis la source de données inscrite dans la transaction.

  4. L'adaptateur envoie le message.

  5. L’adaptateur appelle Terminé sur le lot, en passant sa transaction MSDTC et son pointeur de rappel BatchComplete . Le moteur retourne une interface IBTDTCCommitConfirm .

  6. Le moteur traite le lot, appelle l’adaptateur sur son implémentation BatchComplete et transmet la status de son traitement des messages à l’adaptateur.

  7. Si le lot a réussi, l’adaptateur valide la transaction et appelle l’API IBTDTCCommitConfirm.DTCCommitConfirm avec une true valeur qui signifie commit.

    Image montrant l’interaction entre l’adaptateur et le moteur de messagerie lors d’une soumission transactionnelle de messages entrants.

Émetteurs traités

Les adaptateurs traités sont pour la plupart très similaires aux adaptateurs non traités. La principale différence réside dans le fait que l'adaptateur traité envoie les données du message vers une ressource inscrite dans une transaction MSDTC.

Conseil d’implémentation : Pour les envois traités, l’adaptateur doit utiliser la même transaction MSDTC pour écrire les données dans la destination et pour les supprimer via l’appel de méthode IBTTransportBatch.DeleteMessage . Seules ces deux opérations doivent être traitées. Les autres opérations, telles que IBTTransportBatch.Resubmit, IBTTransportBatch.MoveToNextTransport et IBTTransportBatch.MoveToSuspendQ, n’ont pas besoin d’être traitées. Cela est dû au fait que le moteur utilise implicitement une transaction et que ces types d'opérations n'ont pas besoin d'être atomiques par rapport à la destination.

Le diagramme d'interaction d'objets suivant présente les interactions entre l'adaptateur et le moteur. La séquence d'événements se décompose comme suit :

  1. Le moteur reçoit un nouveau lot de l'adaptateur.

  2. Le moteur ajoute deux messages au nouveau lot.

  3. Le moteur appelle Terminé sur le lot, ce qui oblige l’adaptateur à publier le lot dans sa file d’attente de transmission interne qui est prise en charge par son pool de threads.

  4. L'adaptateur crée et retourne une nouvelle transaction MSDTC.

  5. L'adaptateur transmet les messages en inscrivant la destination dans la transaction MSDTC. Par exemple, il peut s’agir d’écrire dans une base de données SQL Server.

  6. Après la transmission, l'adaptateur reçoit un nouveau lot du moteur.

  7. L’adaptateur appelle DeleteMessage pour les messages qu’il a transmis avec succès.

  8. L’adaptateur appelle Terminé sur le lot en passant sa transaction DTC. Le moteur retourne une interface IBTDTCCommitConfirm .

  9. Le moteur traite le lot et supprime les messages de la file d'attente de l'application.

  10. Le moteur rappelle l’interface IBTBatchCallback de l’adaptateur avec des informations sur la réussite de ses opérations de suppression.

  11. Si le lot a été correctement traité, l'adaptateur valide les transactions.

  12. L’adaptateur appelle IBTDTCCommitConfirm.DTCCommitConfirm pour informer le moteur que la transaction a été validée.

    Image montrant les interactions entre l’adaptateur et le moteur.

Adaptateurs de sollicitation-réponse traités

À la différence des réceptions bidirectionnelles, les envois bidirectionnels peuvent être réalisés à l'aide de la même transaction DTC. Les adaptateurs de sollicitation-réponse traités doivent utiliser le même IBTTransportBatch pour les opérations SubmitResponseMessage et DeleteMessage . Ce lot doit utiliser la même transaction MSDTC utilisée pour envoyer et recevoir la paire de messages de sollicitation-réponse. Il s'agit de garantir l'atomicité de l'échange des messages de sollicitation-réponse.

Composants de service et BYOT

Les API du moteur de messagerie requièrent l'utilisation d'une transaction MSDTC. Cependant, certains composants .NET sont conçus pour être utilisés en tant que composants pris en charge et ne permettent pas la validation ou l'abandon programmés de la transaction. À la place, la transaction est automatiquement validée par COM+ Runtime sur cette plateforme.

Dans ces scénarios, l'adaptateur doit utiliser Bring Your Own Transaction (BYOT). Cela permet à l'adaptateur de créer une transaction MSDTC, d'instancier le composant .NET qui utilise la transaction, et permet à ce composant d'hériter de la transaction créée plutôt que d'avoir à en créer une. Le .NET Framework fournit System.EnterpriseServices.BYOT à cet effet. Le Kit de développement logiciel (SDK) BaseAdapter fournit une classe d’assistance, BYOTTransaction, à cet effet.

Prévention des conditions d'engorgement

Lorsque vous écrivez un adaptateur qui crée un objet de transaction et le remet à BizTalk Server, vous acceptez la responsabilité d’écrire du code qui effectue les opérations suivantes :

  • résout les erreurs dans les messages associés au lot ;

  • décide de l'issue finale de la transaction associée à l'opération de traitement par lot.

    L’adaptateur doit informer BizTalk Server du résultat final de la transaction pour conserver ses données de suivi interne. L’adaptateur informe BizTalk Server du résultat en appelant DTCConfirmCommit. S'il ne le fait pas, une fuite de mémoire sensible se produit.

    Les deux tâches que sont la résolution des erreurs et la décision concernant le résultat final (indiquées ci-dessus) d'un lot envoyé sont en apparence assez simples. En fait, elles s'appuient sur des informations provenant de plusieurs threads :

  • L’adaptateur traite les erreurs en fonction des informations transmises par BizTalk Server au rappel BatchComplete dans l’adaptateur. Ce rappel se trouve sur le thread de l’adaptateur.

  • DTCConfirmCommit est une méthode sur l’objet IBTDTCCommitConfirm . Un instance de l’objet IBTDTCCommitConfirm est retourné par l’appel IBTTransportBatch ::D one par lot. Cette instance se trouve sur le même thread que l’appel IBTTransportBatch ::D one, qui est différent du thread de l’adaptateur.

  • Pour chaque appel que l’adaptateur effectue à IBTTransportBatch ::D’un rappel correspondant, BatchComplete, est appelé par le moteur de messagerie dans un thread distinct pour signaler le résultat de l’envoi par lot. Dans BatchComplete , l’adaptateur doit valider ou restaurer la transaction en fonction de la réussite ou de l’échec du lot. Dans les deux cas, l’adaptateur doit ensuite appeler DTCConfirmCommit pour signaler le status de la transaction au moteur de messagerie.

    Il existe une condition de race possible, car l’implémentation de BatchComplete par l’adaptateur peut supposer que l’objet IBTDTCCommitConfirm retourné par IBTTransportBatch ::D one est toujours disponible lors de l’exécution de BatchComplete . Toutefois, BatchComplete peut être appelé dans un thread de moteur de messagerie distinct, même avant que IBTTransportBatch ::D one retourne. Il est possible que lorsque l’adaptateur tente d’accéder à l’objet IBTDTCCommitConfirm dans le cadre de l’implémentation BatchComplete , il y ait une violation d’accès.

    Le problème est résolu avec un événement dans l’exemple suivant. Ici, le pointeur d'interface fait l'objet d'un accès par l'intermédiaire d'une propriété qui fait appel à un événement. La méthode get attend toujours que la méthode set soit terminée.

protected IBTDTCCommitConfirm CommitConfirm  
{  
   set  
   {  
       this.commitConfirm = value;  
       this.commitConfirmEvent.Set();  
   }  
   get  
   {  
       this.commitConfirmEvent.WaitOne();  
       return this.commitConfirm;  
   }  
}  
protected IBTDTCCommitConfirm commitConfirm = null;  
private ManualResetEvent commitConfirmEvent = new ManualResetEvent(false);  

Affectez maintenant la valeur de retour d’IBTTransportBatch ::D one à cette propriété et utilisez-la dans l’appel BatchComplete .

Voir aussi

Lots de messages transactionnels