Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Rappels par lots
Les lots envoyés par les adaptateurs de réception au moteur de messagerie sont traités de manière asynchrone. Par conséquent, l’adaptateur a besoin d’un mécanisme pour lier un rappel à un état dans l’adaptateur afin qu’il puisse être averti de la réussite ou de l’échec et effectuer toutes les actions de nettoyage nécessaires. La sémantique de rappel est flexible afin que les adaptateurs puissent utiliser une ou une combinaison de trois approches. Ces règles sont les suivantes :
Tous les rappels sont effectués sur la même instance d’objet qui implémente IBTBatchCallBack.
Le cookie passé dans le moteur lors de la demande d’un nouveau lot est utilisé pour mettre en relation le "callback" avec l’état dans les adaptateurs.
Il existe un objet de rappel différent pour chaque lot qui implémente IBTBatchCallBack. Ici, chaque objet contient son propre état privé.
Une fois le traitement du lot effectué, l’adaptateur est appelé de nouveau dans le cadre de son implémentation d’IBTBatchCallBack.BatchComplete. L’état global du lot est indiqué par le premier paramètre, l’état HRESULT. Si cette valeur est supérieure ou égale à zéro, le lot a réussi dans le sens où le moteur possède la propriété des données et que l’adaptateur est libre de supprimer ces données du câble. Un état négatif indique que le lot a échoué : aucune des opérations du lot n’a réussi et l’adaptateur est responsable de la gestion de l’échec.
Si le lot a échoué, l’adaptateur doit savoir quel élément dans lequel l’opération a échoué. Par exemple, supposons que l’adaptateur lit 20 fichiers à partir du disque et les envoie dans BizTalk Server à l’aide d’un seul lot. Si le dixième fichier a été endommagé, l’adaptateur doit suspendre ce fichier et soumettre à nouveau les 19 restants. Ces informations sont disponibles pour l’adaptateur dans les deuxième et troisième paramètres :
opCount(nombre d’opérations) de type court etoperationStatus, qui est de type BTBatchOperationStatus[].
Remarque
Sur un seul objet batch, vous ne devez jamais envoyer un message plusieurs fois. L’envoi du même objet de message plusieurs fois sur le même lot entraîne des erreurs de moteur.
Le nombre d’opérations indique le nombre de types d’opérations dans le lot (taille du tableau BTBatchOperationStatus ). Chaque élément du tableau d’état de l’opération correspond à un type d’opération donné. En utilisant le tableau BTBatchOperationStatus , l’adaptateur peut déterminer quel élément dans une opération donnée a échoué en examinant le tableau BTBatchOperationStatus.MessageStatus pour les valeurs HRESULT négatives signifiant l’échec. Dans le scénario ci-dessus, l’adaptateur crée un lot contenant 19 envois de messages et une suspension de message.
Le fragment de code suivant montre comment un adaptateur demande un nouveau lot à partir du moteur via son proxy de transport et envoie un message unique dans le moteur à l’aide de l’approche de cookie. Le moteur de messagerie appelle la méthode BatchComplete comme rappel par lot lorsqu’il a terminé le traitement de l’ensemble du lot de messages envoyés.
using Microsoft.BizTalk.TransportProxy.Interop;
using Microsoft.BizTalk.Message.Interop;
public class MyAdapter :
IBTTransport,
IBTTransportConfig,
IBTTransportControl,
IPersistPropertyBag,
IBaseComponent,
IBTBatchCallBack
{
private IBTTransportProxy _tp;
public void BatchComplete(
Int32 status,
Int16 opCount,
BTBatchOperationStatus[] operationStatus,
System.Object callbackCookie)
{
// Use cookie to correlate callback with work done,
// in this example the batch is to submit a single
// file the name of which will be in the
// callbackCookie
string fileName = (string)callbackCookie;
if ( status >= 0 )
// DeleteFile from disc
File.Delete(fileName);
else
// Rename file to fileName.bad
File.Move(fileName, fileName + ".bad");
}
private void SubmitMessage(
IBaseMessage msg,
string fileName)
{
// Note: Pass in the filename as the cookie
IBTTransportBatch batch =
_tp.GetBatch(this, (object)fileName);
// Add msg to batch for submitting
batch.SubmitMessage(msg);
// Process this batch
batch.Done(null);
}
}
Le Kit de développement logiciel (SDK) BizTalk Server inclut des exemples pour les adaptateurs suivants : fichier, HTTP, MSMQ et adaptateur transactionnel. Tous ces adaptateurs sont basés sur un bloc de construction commun appelé BaseAdapter. La version 1.0.1 de BaseAdapter inclut tout le code approprié pour analyser l’état de l’opération et reconstruire un nouveau lot à soumettre.
Condition de course
Les deux tâches de résolution des erreurs et de décider du résultat final d’un lot soumis semblent assez simples, mais en fait, elles s’appuient sur des informations provenant de différents threads :
L’adaptateur traite les erreurs en fonction des informations transmises par BizTalk Server à la méthode de rappel BatchComplete de l’adaptateur. Ce rappel s’exécute sur le thread de l’adaptateur.
DTCCommitConfirm est une méthode sur l’objet IBTDTCCommitConfirm . Une instance de l’objet IBTDTCCommitConfirm est retournée par l'appel du lot IBTTransportBatch::Done. Cette instance se trouve sur le même thread que l'appel IBTTransportBatch::Done, ce qui est différent du thread de rappel de l'adaptateur.
Pour chaque appel que l’adaptateur effectue à IBTTransportBatch::Done, le moteur de messagerie effectue un appel correspondant à la méthode de rappel BatchComplete dans un thread distinct afin de signaler le résultat de la soumission par lot. Dans BatchComplete, l'adaptateur doit valider ou annuler la transaction en fonction du succès ou de l'échec du lot. Dans les deux cas, l’adaptateur doit ensuite appeler DTCCommitConfirm pour signaler l’état de la transaction.
Une condition de concurrence possible existe, car l'implémentation de BatchComplete de l'adaptateur peut supposer que l'objet IBTDTCCommitConfirm retourné par IBTTransportBatch::Done est toujours disponible lorsque BatchComplete s'exécute. Toutefois, BatchComplete peut être appelé dans un thread de moteur de messagerie distinct, même avant que IBTTransportBatch::Done retourne. Il est possible que lorsque l’adaptateur tente d’accéder à l’objet IBTDTCCommitConfirm dans le cadre de l’implémentation BatchComplete , il existe une violation d’accès, car cet appel de thread n’existe plus. Utilisez la solution suivante pour éviter cette condition.
Dans l’exemple suivant, le problème est résolu à l’aide d’un événement. Ici, le pointeur d’interface est accessible via une propriété qui utilise l’événement. L’obtention attend toujours que l’ensemble se termine avant de continuer.
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);
Codes d’état du lot
Le code d’état global du lot indique le résultat du lot. L’état de l’opération donne le code d’état de soumission pour les éléments de message individuels. Les lots peuvent échouer pour différentes raisons. Il peut y avoir une défaillance liée à la sécurité, ou le message a peut-être été envoyé lors de l’arrêt du moteur. (Habituellement, lorsque le moteur s’arrête, il n’accepte aucun nouveau travail mais permet l'achèvement du travail en cours.) Le tableau suivant indique certaines valeurs HRESULT courantes qui sont retournées soit dans l’état du lot, soit dans l’état de l’opération. Il indique également s’il s’agit de codes de réussite ou d’échec. La gestion appropriée de ces codes est décrite plus complètement dans How to Handle Adapter Failures.
| Code (défini dans la classe BTTransportProxy) | Code de réussite/échec | Descriptif |
|---|---|---|
| BTS_S_EPM_SECURITY_CHECK_FAILED | Succès | Le port a été configuré pour effectuer une vérification de sécurité et supprimer les messages qui ont échoué à l'authentification. Les adaptateurs ne doivent pas suspendre les lots qui retournent ce code d’état. |
| BTS_S_EPM_MESSAGE_SUSPENDED | Succès | Indique qu’un ou plusieurs messages ont été suspendus et que le moteur possède la propriété des données. Il s’agit d’un code de réussite dans lequel le moteur de messagerie a accepté la soumission du message. |
| E_BTS_URL_DISALLOWED | Échec | Un message a été envoyé avec une inboundTransportLocation non valide. |
Opérations par lots
Le tableau suivant détaille les méthodes et opérations membres de l’objet IBTTransportBatch que l’adaptateur utilise pour ajouter du travail à un lot donné.
| Nom de la méthode | Type d'opération | Descriptif |
|---|---|---|
| SubmitMessage | Envoyer | Envoie un message dans le moteur. |
| SubmitResponseMessage | Envoyer | Envoie un message de réponse dans le moteur. Il s’agit du message de réponse dans une paire de sollicitations-réponse. |
| DeleteMessage | Supprimer | Supprime un message que l'adaptateur a transmis avec succès sur le réseau à l’aide d’un envoi non bloquant. Les adaptateurs qui utilisent des envois bloquants n'ont pas besoin d'appeler cette méthode, car le moteur de messagerie le supprimera pour le compte de l’adaptateur si l’adaptateur renvoie true depuis TransmitMessage. |
| MoveToSuspendQ | MoveToSuspendQ | Déplace un message dans la file d’attente suspendue. |
| Resoumettre | Resoumettre | Demande qu’un message soit retenté pour la transmission ultérieurement. Cela est généralement appelé après l’échec d’une tentative de transmission. |
| PasserAuTransportSuivant | PasserAuTransportSuivant | Demande qu’un message soit transmis à l’aide de son transport de sauvegarde. Généralement appelé après que toutes les nouvelles tentatives ont été épuisées. Si aucun transport de sauvegarde n’est présent, cette méthode échoue |
| SubmitRequestMessage | SoumettreDemande | Envoie un message de demande. Il s’agit d’un message de requête dans une paire demande-réponse. |
| CancelRequestForResponse | CancelRequestForResponse | Avertit le moteur que l’adaptateur ne souhaite plus attendre le message de réponse dans une paire demande-réponse. |
| Effacer | NA | Efface tout le travail du lot. |
| Fait | NA | Envoie un lot de messages au moteur pour traitement. |
Gestion des lots
Les lots sont implémentés dans le code natif au sein du moteur de messagerie. Pour cette raison, un adaptateur écrit dans le code managé doit libérer le wrapper pouvant être appelé au runtime (RCW) pour le lot après l’avoir traité. Cela s’effectue dans le code managé à l’aide de l’API Marshal.ReleaseComObject . Il est important de se rappeler que cette API doit être appelée dans une boucle while jusqu’à ce que le nombre de références retournés atteigne zéro.
BizTalk Server traite les messages de façon synchrone au sein d’un lot. De nombreux lots peuvent être traités simultanément, ce qui peut offrir une possibilité d’optimisation dans l’adaptateur en ajustant la taille du lot dans le domaine d’application. Par exemple, vous pouvez traiter tous les fichiers sur un site FTP (jusqu’à ce qu’une limite soit atteinte). Dans le cas de SAP, vous pouvez traiter un flux unique dans un certain nombre de messages qui sont ensuite envoyés en tant que lot.
Le lot utilisé par un adaptateur pour transmettre des opérations à BizTalk Server n’a pas besoin de correspondre exactement à la liste des messages que BizTalk Server donne à l’adaptateur. En d’autres termes, lorsque vous effectuez des envois transactionnels, vous devez fractionner les opérations de renvoi MoveToNextTransport et MoveToSuspendQ en lots distincts. De nombreux adaptateurs trient un lot de messages qui ont été envoyés pour plusieurs points de terminaison dans des listes distinctes de messages pour un traitement ultérieur.
Le point est qu’il n’existe aucune règle (en plus de celles associées à la transaction) associées au traitement par lots de messages dans BizTalk Server. Le traitement par lots est simplement un moyen spécifique à l’implémentation pour l’adaptateur de segmenter les messages dans et hors de BizTalk Server.
Un adaptateur peut regrouper les messages de plusieurs lots plus petits que lui fournit BizTalk Server dans un lot plus grand pour renvoyer à BizTalk Server. Il peut s’agir d’une optimisation significative dans les adaptateurs transactionnels qui traitent d’un grand nombre de messages très petits. Elle réduit le ratio « nombre total de transactions par message ».
En règle générale, BizTalk Server envoie des lots constitués de 5 à 10 messages. Si ces messages sont très petits, un adaptateur peut traiter jusqu’à 100 messages ou plus avant d’envoyer un lot transactionnel de suppressions à BizTalk Server. Une optimisation comme celle-ci n’est pas facile à implémenter ; vous devez vous assurer que les messages ne sont jamais bloqués dans la mémoire de l’adaptateur, en attendant sans fin que certains seuils soient atteints.
L’importance du traitement par lots est visible dans les numéros de performances de BizTalk Server pour les adaptateurs à débit élevé comme MQSeries. Dans ces adaptateurs, les messages sont reçus au moins deux fois plus souvent qu’ils sont envoyés. Par défaut, l’adaptateur de réception utilise des lots de 100 messages et l’adaptateur d’envoi utilise le lot BizTalk Server par défaut donné.
Lots transactionnels
Lorsque vous écrivez un adaptateur qui crée un objet transactionnel et le remet à BizTalk Server, vous acceptez la responsabilité d’écrire du code qui effectue les opérations suivantes :
Détermine le résultat final de l’opération de traitement par lots : pour valider ou mettre fin à la transaction. Cela peut dépendre d’autres branches transactionnelles dans l’étendue de cette transaction qui ne dépendent pas de BizTalk Server, telles que l’écriture dans une file d’attente Message Queuing (MSMQ) ou une opération de base de données transactionnelle.
Informe BizTalk Server du résultat final en appelant la méthode IBTDTCCommitConfirm.DTCCommitConfirm. Le retour de
trueindique une validation réussie de la transaction ; le retour defalsesignifie l’échec et l’annulation de la transaction.L’adaptateur doit informer BizTalk Server sur le résultat final de la transaction pour conserver ses données de suivi interne. L’adaptateur informe BizTalk Server du résultat en appelant DTCCommitConfirm. Si l’adaptateur ne le fait pas, une fuite de mémoire importante se produit et la transaction MSDTC peut expirer et échouer malgré les opérations effectuées avec succès.