Compartilhar via


Solucionando Problemas: "No transaction is active" no SQL SERVER (pt-BR)

Problema

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.

**Como identificar: **

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.

Analisando o trace do MSDTC

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"             

Solucionando o problema:

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