Come lavorare con i servizi WCF transazionali

WCF (Windows Communication Foundation) è una piattaforma di messaggistica sicura, affidabile e scalabile per lo sviluppo di servizi in .Net.

Una transazione è un insieme di istruzioni che vengono eseguite seguendo i principi ACID (ACID sta per operazioni atomiche, coerenti, isolate e durevoli). Quando una delle operazioni nel blocco della transazione fallisce, l'intera transazione viene interrotta, cioè l'intera transazione fallisce. WCF fornisce supporto per operazioni transazionali distribuite. È possibile sfruttare la classe TransactionScope presente nello spazio dei nomi System.Transactions per una gestione efficiente delle transazioni quando si lavora in .Net.

Implementazione di transazioni WCF

In questa sezione esploreremo come creare servizi WCF transazionali. Per iniziare, crea due servizi WCF. Puoi anche creare un altro progetto (una console o un progetto web) per testare i tuoi servizi. Una volta creati i due servizi WCF, è necessario decorare i contratti di operazione che farebbero parte della transazione con l'attributo TransactionFlow. Ciò è necessario per abilitare il supporto delle transazioni.

Questo attributo accetta l'enumerazione TransactionFlowOption come parametro. TransactionFlowOption può avere uno dei seguenti valori:

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

Quando si lavora con WCF, è prima necessario creare un contratto di servizio e quindi definire le operazioni di servizio oi contratti di operazione in esso. Esistono molti tipi diversi di contratti in WCF: contratti di servizio, contratti dati, contratti di errore, contratti di messaggio e contratti di operazione. In questo esempio utilizzeremo contratti di servizio e contratti operativi poiché gli altri possono essere facoltativi. Un ServiceContract viene utilizzato per specificare le operazioni che sono disponibili per essere utilizzate dal client del servizio. In questa sezione creeremo due contratti di servizio per i due servizi WCF che stiamo usando.

Il frammento di codice seguente illustra come configurare l'attributo TransactionFlow nel contratto di servizio WCF per fornire supporto transazionale. Nota che devi fare lo stesso anche negli altri contratti operativi (che fanno parte della transazione).

[ServiceContract]

public interface IOrderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrder(Order order);

}

Si noti che ogni contratto di servizio dovrebbe avere uno o più contratti di operazione per definire le operazioni esposte sul cavo. Un contratto di operazione viene utilizzato per definire la firma del metodo di servizio e anche il flusso della transazione, la direzione dell'operazione di servizio e, facoltativamente, qualsiasi contratto di errore che può essere associato.

Ecco come apparirà l'interfaccia IOrderHeaderService (contratto di servizio).

[ServiceContract]

public interface IOrderHeaderService

{

    [OperationContract]

    [TransactionFlow(TransactionFlowOption.Allowed  )]

    void AddOrderHeader(OrderHeader orderHeader);

}

Successivamente, dovresti assicurarti che il tuo metodo di servizio sia decorato con TransactionScopeRequired utilizzando l'attributo OperationBehavior. In sostanza, dovresti impostare la proprietà TransactionScopeRequired su "true" nel contratto di operazione, come mostrato nello snippet di codice di seguito. L'istruzione TransactionScopeRequired = true viene utilizzata per specificare che l'operazione del servizio richiede l'esecuzione di un ambito di transazione.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrder(Order order)

{

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

}

La stessa modifica si applica anche all'altra operazione di servizio.

[OperationBehavior(TransactionScopeRequired = true)]

public void AddOrderHeader(OrderHeader orderHeader)

{

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

}

Il passaggio successivo consiste nel configurare il file di configurazione del servizio per abilitare il flusso delle transazioni. Supponendo che tu stia usando wsHttpBinding, ecco come puoi configurare il tuo servizio WCF per fornire il supporto del flusso delle transazioni.

Si noti che quando si lavora con servizi WCF transazionali è possibile specificare facoltativamente una messaggistica affidabile per diluire la possibilità di transazioni interrotte a causa di errori di comunicazione. È inoltre necessario configurare di conseguenza gli endpoint del servizio WCF per sfruttare l'associazione appena definita.

                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.