Ao tentar executar uma transação distribuída você pode receber o erro abaixo e ao executar novamente o mesmo script é executado com sucesso.
OLE DB provider "SQLNCLI10" for linked server "<LinkedServer>" returned message "No transaction is active.".
Msg 7391, Level 16, State 2, Line 4 The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "<LinkedServer>" was unable to begin a distributed transaction.
Este erro pode ocorrer em ambientes com servidores geograficamente distribuídos, pois por default o MSDTC aguarda até 4 segundos na tentativa de alistar-se no DTC do servidor destino, caso o tempo seja maior do que os 4 segundos, o DTC retorna a mensagem de erro “No transaction is active” . A latência do link geralmente é um dos grandes causadores deste problema.
Primeiro precisamos verificar se existe uma comunicação entre o DTC nos dois servidores. Para isto execute o comando abaixo no Prompt de Comando do servidor de destino da transação.
NETSTAT – anbo >c:\netstat.log
Abra o arquivo c:\netstat.log e procure pelo IP do seu servidor de origempara o serviço MSDTC
Nota: Se você fez uma tentativa há menos de 10 minutos, você encontrará o registro para o MSTDC, caso contrário você não o encontrará.
O Windows mantém esta conexão por 10 minutos caso não tenha atividades neste protocolo, caso contrário ele é encerrado, e é exatamente ai que esta o problema, ao tentar restabelecer a conexão e o DTC demora mais de 4 segundos o erro é exibido.
Você pode usar o WinRM que é uma ferramenta da Microsoft que inicia uma transação distribuída ou simplesmente usar um script de sua aplicação, por ex.
set nocount on select getdate() BEGIN DISTRIBUTED TRANSACTION SELECT top 1 * FROM [<LinkedServer>].[msdb].dbo.restorehistory SELECT top 1 * FROM [master].dbo.syslogins COMMIT TRANSACTION
No WinRM você precisa iniciar o arquivo WinRm.exe no servidor destino, no servidor de origem onde a transação é iniciada executar no Prompt de comando RMclient.exe /s <Servidor SQL Server destino>
Se você esta a mais de 10 min sem executar uma tentativa de transação e não tem o registro para o IP da maquina de origem para o serviço do MSDTC na máquina do destino (netstat –anbo) você deverá receber o erro acima.
Após executar o testes acima execute novamente o comando NETSTAT –anbo >c:\netstat.log no servidor de destino. Novamente, verifique se existe o registro para o IP do servidor origem para o serviço MSDTC, você deverá encontrar o registro mesmo recebendo o erro.
Para analisar o trace do MSDTC, precisamos gerar o arquivo, para isto basta seguir as etapas abaixo:
No servidor de origem da transação, em Component Services acesse Computers\My Computer\Distributed Transaction Coordinator\Local DTC clique com o botão direito e clique em properties
Clique em:
1º Flush Data 2º Stop Session 3º New Session
Verifique no Windows Explorer o nome do arquivo mais recente no diretório C:\Windows\System32\MSDTC\Trace
Acesse o prompt de comando do diretório do trace e digite o comando abaixo:
msdtcvtr -tracelog <nome do arquivo de trace> -o c:\traceDTC
No diretório C:\ será gerado um arquivo traceDTC.CSV, ao editar este arquivo veremos mais alguns detalhes sobre o erro
pid=15364 ;tid=18312 ;time=08/25/2011-07:22:13.833 ;seq=3559667 ;eventid=TRANSACTION_PROPOGATION_FAILED_CONNECTION_DOWN_FROM_REMOTE_TM ;tx_guid=d5113606-db6d-4522-9846-2579bf69ed64 ;"TM Identifier='MSDTC$083767b6-f12c-404d-9c4a-3c5944d8276c '" ;"failed to propogate transaction to child node '<servidor>' because the connection with the remote transaction manager went down"
pid=15364 ;tid=18312 ;time=08/25/2011-07:22:13.833 ;seq=3559668 ;eventid=TRANSACTION_ABORTING ;tx_guid=d5113606-db6d-4522-9846-2579bf69ed64 ;"TM Identifier='MSDTC$083767b6-f12c-404d-9c4a-3c5944d8276c '" ;"transaction is aborting"
Para resolver este problema, podemos aumentar este timeout alterando uma chave de registry conforme o KB922430
Para servidores Stand Alone
Na pasta HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC criar a chave DWORD CmMaxNumberBindRetries com valor decimal (60)
Para servidores Clusterizados
Na pasta HKEY_LOCAL_MACHINE\Cluster\Resources\<chave onde esta o recurso do msdtc>\MSDTCPRIVATE\MSDTC criar a chave DWORD CmMaxNumberBindRetries com valor decimal (60) Após a inclusão da chave de registro, deve-se reiniciar o serviço do MSDTC
Nota: O valor informado nesta chave equivale a metade em segundo, para 60 = 30 segs.
http://blogs.msdn.com/b/distributedservices/
The hidden tool – MSDTC Transaction Tracing
Marcelo Fernandes da Silva edited Revision 4. Comment: inclusao de link para hidden tool
Marcelo Fernandes da Silva edited Revision 3. Comment: correção ortográfica e incremento no item solucionando problemas
Luciano Lima [MVP] Brazil edited Revision 2. Comment: Alterado o título para padronização.
Fernando Lugão Veltem edited Revision 1. Comment: Acertos na TOC
Fernando Lugão Veltem edited Original. Comment: alterado tags e título para a forma padrão e adicionado TOC