Sin pasar por la restricción de comprobación en el bloque CATCH de transacciones distribuidas
-
23-08-2019 - |
Pregunta
Tengo un procedimiento almacenado MSSSQL realizar una transacción distribuida que tiene este aspecto:
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
Esto funciona bien.
Si añado esta declaración tercera inserción:
insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');
... se produce un error correctamente -. La transacción se revierte en el servidor remoto y el control pasa al bloque CATCH y me da información sobre el error (no se puede convertir 'error' a int)
Pero si añado esta instrucción de inserción:
insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');
.. y tengo una contraint cheque en la tabla remota que requiere valores> 0 en la columna id, entonces las cosas no funcionan como espero. La transacción ¿Tiene retroceder, pero el control no transferencia al bloque catch. En cambio, la ejecución simplemente muere y esto se imprime en la ventana de salida:
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction
¿Por qué? Necesito registrar estos errores en el blog de captura.
Solución
Desde el coordinador de transacciones distribuidas está manejando esto, cuando la transacción falla en la parte distribuida de la transacción, el DTC envía un mensaje en forma de una atención, que detiene su código de ejecución, y que el TRY / CATCH no puede proceso.
SQL Server puede detectar en su final cuando se está tratando de insertar un tipo de datos incorrectos en una tabla (incluso en una instancia remota), pero la restricción se procesa en el servidor vinculado, lo que hace que la atención para ser enviado a DTC y su try / catch para ser ignorada.
Para obtener más información, véase la primera sección "Nota" en el "Uso TRY ... CATCH en Transact-SQL" de SQL Server 2008 Libros en pantalla, que se encuentra en: