Verifique bloco CATCH restrição Ignorando em Distributed Transaction
-
23-08-2019 - |
Pergunta
Eu tenho um procedimento armazenado MSSSQL realizando uma transação distribuída parecida com esta:
SET XACT_ABORT ON;
SET NOCOUNT ON;
BEGIN TRY
BEGIN DISTRIBUTED TRANSACTION
insert into LNKSRV.INST.dbo.zz (id, val) values (1, 'a');
insert into LNKSRV.INST.dbo.zz (id, val) values (2, 'b');
COMMIT TRANSACTION
END TRY
BEGIN CATCH
if (XACT_STATE() <> 0)
BEGIN
ROLLBACK TRANSACTION;
END
print ERROR_MESSAGE();
print ERROR_LINE();
print ERROR_SEVERITY();
END CATCH
Esta multa funciona.
Se eu adicionar esta terceira instrução de inserção:
insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');
... ele falhar corretamente -. A transação é revertida no servidor remoto e controle passa para o bloco CATCH e eu obter informações sobre o erro (não é possível converter 'error' para int)
Mas se eu adicionar esta instrução de inserção:
insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');
.. e eu tenho um contraint verificação na tabela remota exigindo valores> 0 na coluna id, então as coisas não funcionam como eu esperava. A transação O rolo de volta, mas o controle não transferência para o bloco catch. Em vez disso, a execução apenas morre e isso é impresso na janela de saída:
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction
Por quê? Eu preciso registrar esses erros no blog captura.
Solução
Uma vez que o coordenador de transações distribuídas está a lidar com isso, quando a transação falha por parte distribuída da transação, o DTC envia uma mensagem na forma de uma atenção, o que impede o seu código seja executado, e que o try / catch não pode processo.
SQL Server pode detectar no seu final, quando você está tentando inserir um tipo de dados incorretos em uma tabela (mesmo em uma instância remota), mas a restrição é processado no servidor vinculado, o que faz com que a atenção seja enviada para DTC e o try / catch para ser ignorado.
Para obter mais informações, consulte a primeira secção "Nota" no "Usando TRY ... CATCH na Transact-SQL" do SQL Server 2008 Books Online, localizado em: