1

J'essaye de créer un System.EnterpriseServices.ServicedComponent afin de participer à une transaction distribuée. Ma principale méthode ressemble à ceci:Comment détecter un abandon de transaction dans un composant Serviced?

public void DoSomething() 
{ 
    try 
    { 
     // do something useful 

     // vote for commit 

     if (ContextUtil.IsInTransaction) 
      ContextUtil.MyTransactionVote = TransactionVote.Commit; 
    } 

    catch 
    { 
     // or shoud I use ContextUtil.SetAbort() instead? 

     if (ContextUtil.IsInTransaction) 
      ContextUtil.MyTransactionVote = TransactionVote.Abort; 

     throw; 
    } 
} 

Ce que je suis en train de faire est de détecter si la transaction distribuée a été annulée (ou annulée), puis passez à rollback mes changements. Par exemple, j'ai peut-être créé un fichier sur le disque ou fait des effets secondaires qui doivent être annulés.

J'ai essayé de gérer l'événement SystemTransaction.TransactionCompleted ou inspecté l'état du SystemTransaction dans la méthode Dispose() sans succès.

Je comprends que ce qui est similaire à la « compensation » plutôt que de « transaction ».

Est-ce que ce que j'essaie de faire a même du sens?

+0

Eh bien, répondre genre de ma propre question, cela est possible en dérivant la ServicedComponent de System.Transactions.IEnlistmentNotification ainsi. Cependant, je n'arrivais pas à faire fonctionner ceci - plutôt, j'ai systématiquement obtenu une exception ObjectDisposedException. –

Répondre

1

Je recommanderais de ne pas gérer la transaction de cette manière, sauf si vous en avez besoin.

Si vous voulez que votre opération de vote abort si l'une des autres opérations impliquées dans la chaîne échouent, ou voter pour engager si tout allait bien; il suffit de placer un [AutoComplete] atttribute (voir Remarques section à ce article) juste au-dessus de la déclaration de votre méthode.

De cette façon, la transaction en cours sera annulée au cas où une exception pose et sera terminée autrement, automatiquement.

le code ci-dessous Tenir compte (cela pourrait être une classe de composant de service typique):

using System.EnterpriseServices; 

// Description of this serviced component 
[Description("This is dummy serviced component")] 
public MyServicedComponent : ServicedComponent, IMyServiceProvider 
{ 
    [AutoComplete] 
    public DoSomething() 
    { 
     try { 
      OtherServicedComponent component = new OtherServicedComponent() 
      component.DoSomethingElse(); 

      // All the other invocations involved in the current transaction 
      // went fine... let's servicedcomponet vote for commit automatically 
      // due to [AutoComplete] attribute 
     } 
     catch (Exception e) 
     { 
      // Log the failure and let the exception go 
      throw e; 
     } 
    } 
} 
+0

Merci pour une suggestion détaillée. –

+0

De rien Maxime, en fait je me suis rendu compte trop tard que c'était un post assez ancien, mais qui pourrait être utile pour quelqu'un d'autre. –