WCF - Transações

Uma transação no WCF é um conjunto de operações que seguem algumas propriedades, conhecidas coletivamente como ACID. Aqui, se uma única operação falhar, todo o sistema falhará automaticamente. Quando um pedido é feito online, uma transação ocorre. O exemplo a seguir pode ser útil para entender o processo de transação em termos mais simples.

Exemplo

Suponha que você tenha pedido uma televisão LCD de uma loja online e vá pagar o valor com cartão de crédito. Quando você insere as informações necessárias para fazer o pedido, duas operações ocorrem simultaneamente.

Um, o valor especificado é debitado de sua conta bancária e, segundo, a conta do fornecedor é creditada com o mesmo valor. Ambas as operações devem ser executadas com sucesso para que a transação seja bem-sucedida.

Propriedades de transação WCF

As quatro propriedades seguidas por uma transação WCF são as seguintes -

  • Atomic - Todas as operações devem atuar como uma única operação indivisível na conclusão de uma transação.

  • Consistency - Qualquer que seja a operação definida, o sistema está sempre em estado de consistência, ou seja, o resultado da transação é sempre conforme a expectativa.

  • Isolation - O estado intermediário do sistema não é visível para nenhuma entidade do mundo exterior até que a transação seja concluída.

  • Durability - O estado confirmado é mantido independentemente de qualquer tipo de falha (hardware, queda de energia, etc.)

Ao configurar uma transação WCF, existem alguns fatores que exigem consideração. Estes são os comportamentos de ligação e operação.

Binding- As ligações que oferecem suporte à transação no WCF são apenas algumas e é vital fazer uma escolha entre apenas essas ligações, que permanecem desabilitadas por padrão e devem ser habilitadas para obter o suporte necessário para a transação. Essas ligações são as seguintes -

  • NetTcpBinding
  • NetNamedPipeBinding
  • WSHttpBinding
  • WSDualHttpBinding
  • WSFederationHttpBinding

Operation behavior- Enquanto uma ligação facilita o caminho para a propagação da transação, uma operação cuida do processamento da transação, bem como da configuração da operação. O comportamento da operação usa principalmente dois atributos: TransactionFlow e TransactionScopeRequired. Aqui, deve-se observar que TransactionFlow tem principalmente três valores e são: Permitido, Obrigatório e Não Permitido.

O código a seguir mostra se a alteração da configuração de ligação e contrato de operação facilita ou não a propagação do cliente.

<bindings> 
   <wsHttpBinding> 
      <binding name = "MandatoryTransBinding" transactionFlow = "true"> 
         <reliableSession enabled ="true"/>
      </binding>
   </wsHttpBinding> 
</bindings>

Protocolo de Transação

O WCF usa três tipos de protocolos para transações -

  • Lightweight
  • Transação Ole
  • Transação WS-Atomic (WS-AT)

De todos os três, o WS-AT é um protocolo interoperável e permite o fluxo de transações distribuídas entre firewalls. No entanto, este protocolo não deve ser usado quando a transação for estritamente baseada em tecnologia Microsoft.

Fases da transação WCF

Existem duas fases em uma transação WCF, conforme mostrado na figura a seguir.

  • Prepare Phase - Nesta fase, o gerenciador de transações verifica se todas as entidades estão prontas para confirmar a transação ou não.

  • Commit Phase - Nesta fase, o empenho das entidades começa na realidade.

A figura a seguir ilustra as funções de ambas as fases de uma transação WCF.

Habilitando uma transação WCF

Para habilitar uma transação WCF com sucesso, é necessário seguir uma série de seis etapas de maneira sequencial. As etapas necessárias são discutidas abaixo.

Step 1 − Creation of two WCF Services

A primeira etapa a esse respeito é construir dois projetos de serviço no WCF para participar de uma única transação. As transações de banco de dados serão executadas em ambos os serviços e será entendido como eles são unificados por uma transação WCF. Um aplicativo da web de WCFTransactions também foi criado para consumir os dois serviços criados em um único escopo de transação.

Step 2 − Method creation and its attribution with TransactionFlow attribute

Aqui, um método UpdateData será criado para ambos os serviços WCF para inserir no banco de dados com o atributo OperationContract. Para realizar essa tarefa, uma classe de interface é criada primeiro com a ajuda do atributo ServiceContract. Para ativar a transação no método recém-criado, ela é atribuída com TransactionFlow e as transações são permitidas usando seu valor Permitido.

[ServiceContract]
public interface IService1 {
   [OperationContract]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   void UpdateData();
}

Step 3− Implementation of WCF service with TransactionScopeRequired attribute

Isso é feito usando o código mostrado abaixo -

[OperationBehavior(TransactionScopeRequired = true)]
public void UpdateData() {
   try {
      SqlConnection objConnection = new SqlConnection(strConnection);
      objConnection.Open();
      
      using(SqlTransaction transaction = Program.dbConnection.BeginTransaction()) {
     	   Boolean doRollback = false;
     	   using(SqlCommand cmd = new SqlCommand(
            "insert into Customer (Customer name, Customer code) values ('sss', 'sss')"objConnection))
         
     	   try {
            cmd.ExecuteNonQuery();
     	   } catch(SqlException) {
            doRollback = true;
            break;
     	   }
      }
      
      if(doRollback)
         transaction.Rollback();
      else
         transaction.Commit();  
   }
   finally {
      objConection.Close();
   }
}

Step 4 − Enabling Transaction Flow by WCF Service Config File

Sua codificação é feita da seguinte maneira -

<bindings>
   <wsHttpBinding>
      <binding name = "TransactionalBind" transactionFlow = "true"/>
   </wsHttpBinding>
</bindings>

É vital anexar a ligação permitida da transação com o ponto de extremidade para expor o serviço WCF.

<endpoint address = "" binding = "wsHttpBinding" bindingConfiguration = "TransactionalBind" contract = "WcfService1.IService1">

Step 5 − Calling both the services in a single transaction

Aqui, os dois serviços acima são chamados em uma transação e, para esse propósito, o objeto TransactionScope é usado para agrupar os dois serviços. O método Complete do objeto acima é chamado para confirmar uma transação WCF. Para reverter, o método Dispose deve ser chamado.

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      // Call your webservice transactions here
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

A pequena parte do código completo em que as transações WCF foram agrupadas em um escopo é ilustrada abaixo -

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {
   try {
      ServiceReference1.Service1Client obj = newServiceReference1.Service1Client();
      obj.UpdateData();
      ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
      obj1.UpdateData();
      ts.Complete();
   } catch (Exception ex) {
      ts.Dispose();
   }
}

Step 6 − Testing WCF transaction

O teste é feito na 6ª e última etapa e, após chamar o primeiro serviço WCF, uma exceção é forçada.