Cómo trabajar con servicios WCF transaccionales

WCF (Windows Communication Foundation) es una plataforma de mensajería segura, confiable y escalable para desarrollar servicios en .Net.

Una transacción es un conjunto de declaraciones que se ejecutan siguiendo los principios de ACID (ACID significa operaciones atómicas, consistentes, aisladas y duraderas). Cuando falla una de las operaciones en el bloque de transacciones, se aborta toda la transacción, es decir, toda la transacción falla. WCF proporciona soporte para operaciones transaccionales distribuidas. Puede aprovechar la clase TransactionScope presente en el espacio de nombres System.Transactions para una gestión eficiente de las transacciones cuando trabaja en .Net.

Implementación de transacciones WCF

En esta sección, exploraremos cómo podemos crear servicios WCF transaccionales. Para comenzar, cree dos servicios WCF. También puede crear otro proyecto (una consola o un proyecto web) para probar sus servicios. Una vez que se han creado los dos servicios WCF, debe decorar los contratos de operación que serían parte de la transacción con el atributo TransactionFlow. Esto es necesario para habilitar el soporte de transacciones.

Este atributo acepta la enumeración TransactionFlowOption como parámetro. TransactionFlowOption puede tener uno de los siguientes valores:

  • TransactionFlowOption.Allowed
  • TransactionFlowOption.Mandatory
  • TransactionFlowOption.NotAllowed

Al trabajar con WCF, primero debe crear un contrato de servicio y luego definir las operaciones de servicio o los contratos de operación en él. Tiene muchos tipos diferentes de contratos en WCF: contratos de servicio, contratos de datos, contratos de fallas, contratos de mensajes y contratos de operación. En este ejemplo usaremos contratos de servicio y contratos de operación, ya que los otros pueden ser opcionales. Un ServiceContract se utiliza para especificar las operaciones que están disponibles para que las consuma el cliente del servicio. En esta sección, crearemos dos contratos de servicio para los dos servicios WCF que estamos usando.

El siguiente fragmento de código ilustra cómo puede configurar el atributo TransactionFlow en su contrato de servicio WCF para proporcionar compatibilidad transaccional. Tenga en cuenta que también debe hacer lo mismo en los demás contratos de operación (que son parte de la transacción).

[ServiceContract]

public interface IOrderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrder(Order order);

}

Tenga en cuenta que cada contrato de servicio debe tener uno o más contratos de operación para definir las operaciones que se exponen a través del cable. Un contrato de operación se utiliza para definir la firma del método de servicio y también el flujo de transacción, la dirección de la operación del servicio y, opcionalmente, cualquier contrato (s) de falla que pueda estar asociado.

Así es como se vería la interfaz IOrderHeaderService (contrato de servicio).

[ServiceContract]

public interface IOrderHeaderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrderHeader(OrderHeader orderHeader);

}

A continuación, debe asegurarse de que su método de servicio esté decorado con TransactionScopeRequired utilizando el atributo OperationBehavior. En esencia, debe establecer la propiedad TransactionScopeRequired en "true" en el contrato de operación como se muestra en el fragmento de código a continuación. La instrucción TransactionScopeRequired = true se usa para especificar que la operación del servicio necesita un alcance de transacción para ejecutarse.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrder(Order order)

{

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

}

El mismo cambio se aplica también a la otra operación del servicio.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrderHeader(OrderHeader orderHeader)

{

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

}

El siguiente paso es configurar su archivo de configuración de servicio para habilitar el flujo de transacciones. Suponiendo que está utilizando wsHttpBinding, así es como puede configurar su servicio WCF para proporcionar compatibilidad con el flujo de transacciones.

Tenga en cuenta que al trabajar con servicios WCF transaccionales, opcionalmente, puede especificar mensajes confiables para diluir la posibilidad de transacciones canceladas debido a fallas de comunicación. También debe configurar sus puntos finales de servicio WCF en consecuencia para aprovechar el enlace que acabamos de definir.

                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.