A implementação é bem simples e requer que o MSDTC das máquinas estejam habilitados e configurados corretamente, isto garantirá que as máquinas tenham uma comunicação eficaz e garanta o conceito ACID na ação.
Exemplo de configuração do MSDTC:
Para acessar o MSDTC, acesse o "Control Panel" do Windows e entre na opção "Administrative Tools" e logo em seguida em "Component Services". Ao abrir a janela, expanda os itens "Component Services" e "Computers". Clique com o botão direito sobre o "My Computer" e acesse o item "Properties", conforme imagem abaixo.
Na aba MSDTC, habilite-o e realize a configuração.
Exemplo de configuração:
Exemplo de configuração do "Security Configuration":
Habilitando a transação distribuída no código:
Em primeiro momento para habilitar a transação no serviço você necessitará alterar o arquivo de configuração, colocando no binding o atributo transactionFlow e também habilitar a sessão (reliableSession), conforme exemplo abaixo que expoe o protocolo net.tcp:
<netTcpBinding>
<binding name="TransacaoBinding" transactionFlow="true">
<reliableSession enabled="true"/>
<security />
</binding>
</netTcpBinding>
Na interface do serviço precisaremos identificar que aquele contrato tem o atributo SessionMode como Required no attribute ServiceContract.
Para todos os métodos que necessitarem da transação distribuída, deve-se adicionar o attribute TransactionFlow com a opção Allowed (permite transação) ou Mandatory (transação obrigatória).
//Interface do Serviço
[ServiceContract(SessionMode = SessionMode.Required)]
public interface ITesteService
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
bool EfetuarTransferencia(...);
}
Na implementação do serviço será necessário habilitar o atributo TransactionScopeRequired, informando que ele é necessário para este caso.
Dentro da implementação do serviço, utilize o objeto TransactionScope com o atributo TransactionScopeOption na opção Required, para que a transação criada pelo client possa ser utilizada e permita que o conceito ACID seja aplicado.
//Implementação do Serviço
[ServiceBehavior()]
public class TesteService : ITesteService
{
[OperationBehavior(TransactionScopeRequired = true)]
public bool EfetuarTransferencia(...)
{
//Utilize o TransactionScopeOption como Required, para que a transação utilizada seja a mesma da chamada do client.
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
//Realizar alguma ação para gravar em banco de dados.
ts.Complete();
}
}
}
IMPORTANTE: Nesta implementação quando for chamado o método "Complete" do TransactionScope no serviço, o que estiver dentro da transação será marcado como ok e somente se o client realizar o Complete da mesma transação, as ações que participarem desta transação serão aplicadas em definitivo.
Lembrando que no "Dispose" do objeto, as informações são descartadas.
No lado do client:
Para o client, será necessário somente adicionar a referência do serviço e realizar a chamada ao método que requer transação utilizando o "TransactionScopeOption" como "RequiresNew" ou "Required".
Exemplo:
static void Main(string[] args)
{
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
//Realizar alguma ação que necessite da transação
//Chamar o serviço
ServiceReference1.TesteServiceClient servico = new ServiceReference1.TesteServiceClient();
servico.EfetuarTransferencia(...);
//Commit da transação
ts.Complete();
servico.Close();
}
}
Referências:
MSDN - WS Transaction Flow
MSDN - WCF Transaction Propagation



0 comentários:
Postar um comentário