É possível compartilhar uma transação entre uma aplicação .Net e um objeto COM+?
-
09-06-2019 - |
Pergunta
Fiz alguns testes há um tempo e nunca descobri como fazer isso funcionar.
Os ingredientes:
- Objeto transacional COM+ (desenvolvido em VB6)
- Aplicativo web .Net (com transação) no IIS que...
faz uma chamada para o componente COM+
atualiza uma linha em um banco de dados SQL
Teste:
Execute o aplicativo .Net e force uma exceção.
Resultado:
A atualização feita a partir do aplicativo .Net é revertida.
A atualização feita pelo objeto COM+ não é revertida.
Se eu chamar o objeto COM+ de uma página ASP antiga, a reversão funcionará.
Eu sei que algumas pessoas podem estar pensando “o quê?!COM+ e .Net, você deve estar louco!", mas existem alguns lugares neste mundo onde ainda existem muitos componentes COM+.Eu só estava curioso para saber se alguém já enfrentou isso e se você descobriu como fazer isso funcionar.
Solução
Como o VB e o .NET usarão conexões SQL diferentes (e não há como fazer com que o ADO e o ADO.NET compartilhem a mesma conexão), sua única possibilidade é inscrever o DTC (Distributed Transaction Coordinator).O DTC coordenará as duas transações independentes para que elas sejam confirmadas ou revertidas juntas.
Do .NET, o EnterpriseServices gerencia a funcionalidade COM+, como o DTC.No .NET 2.0 e posteriores, você pode usar o namespace System.Transactions, o que torna as coisas um pouco mais agradáveis.Acho que algo assim deveria funcionar (código não testado):
void SomeMethod()
{
EnterpriseServicesInteropOption e = EnterpriseServicesInteropOption.Full;
using (TransactionScope s = new TransactionScope(e))
{
MyComPlusClass o = new MyComPlusClass();
o.SomeTransactionalMethod();
}
}
Não estou familiarizado o suficiente com isso para lhe dar mais conselhos neste momento.
Do lado COM+, seu objeto precisa ser configurado para usar (provavelmente "exigir") uma transação distribuída.Você pode fazer isso no COM+ Explorer, acessando o arquivo Propriedades, selecionando o Transação guia e clicando em "Obrigatório".Não me lembro se você também pode fazer isso a partir do código;O VB6 foi criado antes do lançamento do COM+, portanto, ele não suporta totalmente tudo o que o COM+ faz (seu suporte transacional foi destinado ao antecessor do COM+, chamado MS Transaction Server).
Se tudo funcionar corretamente, seu objeto COM+ deverá estar inscrito no Contexto existente criado pelo seu código .NET.
Você pode usar o nó "Coordenador de transações distribuídas\Lista de transações" em "Serviços de componentes" para verificar e ver a transação distribuída que está sendo criada durante a chamada.
Esteja ciente de que você não pode ver as alterações do componente COM+ refletidas nas consultas de dados do lado .NET até que a transação seja confirmada!Na verdade, é possível um impasse!Lembre-se de que o DTC garantirá que as duas transações estejam emparelhadas, mas ainda serão transações de banco de dados separadas.
Outras dicas
Como você está implementando isso?Se você estiver usando EnterpriseServices para gerenciar a transação .NET, ambas as transações deverão ser revertidas, já que você está usando o mesmo contexto para ambas.