MSDTC Internals
Essa semana me surpreendi com o SQL Saturday #325 . Fiquei tão empolgado que resolvi investir um tempo para escrever esse post. A escolha do tema foi através de uma conversa no twitter. Obrigado @DemetrioSQLDBA e @SQLInsane pela sugestão.
Frequentemente associamos o SQL Server às operações transacionais. Todas as informações são consistentes graças ao Transaction Log.
Entretanto, existe um serviço nativo do Windows chamado Microsoft Distributed Transaction Coordinator (MSDTC). Esse serviço executa as transações utilizando o protocolo chamado 2-Phase Commit. Qualquer recurso pode participar de uma transação distribuída. Por exemplo:
- SQL Server (claro!)
- Servidores Oracle
- Filas IBM MQSeries
- Componentes COM+
A arquitetura do MSDTC é composta por dois grandes componentes: Transaction Manager (TM) e Connection Manager (CM).
Transaction Manager
O componente do Transaction Manager (TM) é responsável por implementar o protocolo 2-Phase Commit. Embora ninguém fale desse jeito, gosto de pensar que as fases são:
- Persistência de dados – TM garante que as informações estão gravadas em disco
- Disponibilidade – O serviço do TM estará disponível para efetivar a modificação
Portanto, quando uma transação distribuída ocorre, todas as informações devem ser gravadas em seu respectivo storage em uma primeira fase. SQL Server armazena a informação no Transaction Log. Da mesma forma, imagino que o Oracle guarda os dados no Redo Log e o MQSeries armazena a mensagem em disco. Embora as informações estejam gravadas em log, elas ainda não estão disponíveis para a aplicação.
Durante a segunda fase, o MSDTC efetiva todas as transações.
- Se qualquer recurso falhou na “fase 1 – persistência de dados” , então todas os recursos falham e fazem o ROLLBACK da informação. Parece estranho pensar que o SQL Server faz rollback do Transaction Log, mas é exatamente isso que ocorre no 2-Phase Commit.
- Se *TODOS* os recursos conseguiram gravar os dados em disco, então é declarada a efetivação dos dados (COMMIT).
Observamos que o principal objetivo do MSDTC é coordenar os recursos transacionais (SQL, Oracle, MQ) usando o conceito de COMMIT ou ROLLBACK. Aqui existe a curiosa situação da transação IN-DOUBT:
- Falhas durante a primeira fase causam o ROLLBACK
- Falhas durante a segunda fase não afetam as transações, que já foram declaradas como COMMIT
- Indisponibilidade de máquina na primeira fase tornam a transação IN-DOUBT – e a resolução é feita quando a máquina volta ao ar
Connection Manager
Em geral, existe um Transaction Manager (TM) por máquina. O serviço do MSDTC utiliza o protocolo RPC para se manter conectado com os demais TM.
RPC é um protocolo antigo e complexo. Todas as máquinas devem disponibilizar o serviço do RPC Locator na porta TCP 135, além de alocar dinamicamente uma porta TCP aleatória. Isso sempre causa dor de cabeça na hora de configurar o firewall. Já cansei de recomendar o artigo abaixo.
Configurando Microsoft coordenador de transações distribuídas (DTC) para trabalhar por meio de um firewall
https://support2.microsoft.com/kb/250367
Em geral, os problemas do MSDTC relacionados à conectividade podem ser facilmente diagnosticados com o DTCPing.
MSDTC não suportado?
Vou deixar como um desafio: você sabe por que o MSDTC não é suportado em um ambiente com Database Mirroring ou Availability Group? A explicação é similar ao motivo de não recomendarmos MSDTC local em instâncias clusterizadas.
Comments
Anonymous
September 30, 2014
Olá Mestre Catae. O MSDTC não é suportado em ambientes com Database Mirroring e AG por causa da possibilidade de ocorrer uma problema de integridade dos dados em casos de failover. Após um failover, o MSDTC não conhece a nova instância primária do SQL Server pois ela não fazia parte da transação original e encerra todas as transações que estão para sofrer o COMMIT. O Bob Dorr escreveu um artigo interessante a respeito do AlwaysOn: Not-Supported: AGs With DTC/Cross-Database Transactions blogs.msdn.com/.../not-supported-ags-with-dtc-cross-database-transactions.aspxAnonymous
September 30, 2014
Leandro isso também é valido para Cluster 2008???Anonymous
October 01, 2014
Leandro, é exatamente isso que acontece. Em caso de uma falha, a nova instância ainda aponta para o MSDTC do servidor antigo. Se esse servidor estiver offline, então as transações ficam em IN-DOUBT esperando até que o servidor inicial fique online (transição da fase 1 para a 2). Gostaria de adicionar um comentário: o artigo do Bob Dorr é indiscutivelmente muito bom (pra variar). Entretanto, ele comenta sobre o MSDTC e Múltiplos banco de dados (cross database). No primeiro caso, as transações ficam pendentes em in-doubt. Porém, é no segundo caso que pode haver problemas de chave primária e estrangeira (erro de integridade referencial). Obrigado pelo seu comentário!Anonymous
October 01, 2014
Tiago, o MSDTC funciona normalmente com o Cluster 2008. O problema é usar bancos de dados com Mirroring ou participando do Availability Group. Nesse caso, a recomendação é evitar o MSDTC.Anonymous
October 01, 2014
Mestre Catae, sei que é da concorrência, mas vou deixar aqui uma dica, porque sempre peguei pelo caminho DBAs Oracle que não conheciam essa feature. Em um cenário de integração / ETL trazendo dados do Oracle para SQL Server utilizando o SSIS, precisava utilizar o MSDTC e para o Oracle funcionar ele precisa de um componente: MTS Oracle Services for Microsoft Transaction Server (www.oracle.com/.../index-089915.html) que normalmente o pessoal nem sabe o que é :PAnonymous
October 01, 2014
Ótima dica! Eu mesmo nao conhecia esse componente. Imagino que ele seja instalado no lado do cliente (aplicação).Anonymous
January 02, 2015
muito boa dica amigo Fabricio vou ficar ligado !! abraço