Comment travailler avec les services WCF transactionnels

WCF (Windows Communication Foundation) est une plate-forme de messagerie sécurisée, fiable et évolutive pour le développement de services en .Net.

Une transaction est un ensemble d'instructions qui sont exécutées en suivant les principes ACID (ACID signifie opérations atomiques, cohérentes, isolées et durables). Lorsqu'une des opérations du bloc de transaction échoue, la transaction entière est abandonnée, c'est-à-dire que la transaction entière échoue. WCF prend en charge les opérations transactionnelles distribuées. Vous pouvez tirer parti de la classe TransactionScope présente dans l'espace de noms System.Transactions pour une gestion efficace des transactions lorsque vous travaillez dans .Net.

Implémentation des transactions WCF

Dans cette section, nous allons explorer comment nous pouvons créer des services WCF transactionnels. Pour commencer, créez deux services WCF. Vous pouvez également créer un autre projet (une console ou un projet Web) pour tester vos services. Une fois les deux services WCF créés, vous devez décorer les contrats d'opération qui feraient partie de la transaction avec l'attribut TransactionFlow. Cela est nécessaire pour activer la prise en charge des transactions.

Cet attribut accepte l'énumération TransactionFlowOption en tant que paramètre. Le TransactionFlowOption peut avoir l'une des valeurs suivantes:

  • TransactionFlowOption.Allowed
  • TransactionFlowOption.Obligatoire
  • TransactionFlowOption.NotAllowed

Lorsque vous travaillez avec WCF, vous devez d'abord créer un contrat de service, puis définir les opérations de service ou les contrats d'opération qu'il contient. Vous disposez de nombreux types de contrats différents dans WCF - contrats de service, contrats de données, contrats d'erreur, contrats de message et contrats d'exploitation. Dans cet exemple, nous utiliserons des contrats de service et des contrats d'exploitation car les autres peuvent être optionnels. Un ServiceContract est utilisé pour spécifier les opérations que le client de service peut utiliser. Dans cette section, nous allons créer deux contrats de service pour les deux services WCF que nous utilisons.

L'extrait de code suivant illustre comment vous pouvez configurer l'attribut TransactionFlow dans votre contrat de service WCF pour fournir une prise en charge transactionnelle. Notez que vous devez également faire de même dans les autres contrats d'opération (qui font partie de la transaction).

[ServiceContract]

public interface IOrderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrder(Order order);

}

Notez que chaque contrat de service doit avoir un ou plusieurs contrats d'exploitation pour définir les opérations qui sont exposées sur le fil. Un contrat d'exploitation permet de définir la signature de la méthode de service ainsi que le flux de transaction, la direction de l'opération de service et éventuellement, tout contrat de panne qui peut être associé.

Voici à quoi ressemblerait l'interface IOrderHeaderService (contrat de service).

[ServiceContract]

public interface IOrderHeaderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrderHeader(OrderHeader orderHeader);

}

Ensuite, vous devez vous assurer que votre méthode de service est décorée avec TransactionScopeRequired à l'aide de l'attribut OperationBehavior. En substance, vous devez définir la propriété TransactionScopeRequired sur "true" dans le contrat d'opération, comme indiqué dans l'extrait de code ci-dessous. L'instruction TransactionScopeRequired = true est utilisée pour spécifier que l'opération de service nécessite une étendue de transaction pour être exécutée.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrder(Order order)

{

   // Write code here to add an order record to the database

}

Le même changement s'applique également à l'autre opération de service.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrderHeader(OrderHeader orderHeader)

{

   // Write code here to add an order header record to the database

}

L'étape suivante consiste à configurer votre fichier de configuration de service pour activer le flux de transactions. En supposant que vous utilisez wsHttpBinding, voici comment vous pouvez configurer votre service WCF pour fournir la prise en charge du flux de transactions.

Notez que lorsque vous travaillez avec des services WCF transactionnels, vous pouvez éventuellement spécifier une messagerie fiable pour diluer la possibilité de transactions annulées en raison d'échecs de communication. Vous devez également configurer vos points de terminaison de service WCF en conséquence pour tirer parti de la liaison que nous venons de définir.

                bindingConfiguration="Transactional" contract="Services.IOrderService">

You would now need to take advantage of the TransactionScope class present in the System.Transactions namespace to call your services from within one transaction scope. Typically you can use this class to implement transaction scope for handling interdependent transactions and resolve concurrency conflicts when working with ADO.Net.

try

{

  using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))

  {

    // Write code here to call the service methods of your services here

    transactionScope.Complete();

  }

}

catch

{

  //Write code here to handle exceptions

}

And that's all you need to do. You can now execute your application and test your transactional services.