次のような分散トランザクションを実行する MSSSQL ストアド プロシージャがあります。
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
これはうまくいきます。
この 3 番目の挿入ステートメントを追加すると、次のようになります。
insert into LNKSRV.INST.dbo.zz (id, val) values ('error', 'b');
...正しく失敗します-トランザクションはリモートサーバーでロールバックされ、制御がCATCHブロックに渡され、エラーに関する情報が取得されます(「エラー」をintに変換できません)。
しかし、この挿入ステートメントを追加すると:
insert into LNKSRV.INST.dbo.zz (id, val) values (-1, 'b');
..そして、id 列の値 > 0 を要求するリモート テーブルにチェック制約があると、期待どおりに動作しません。トランザクションはロールバックしますが、制御はcatchブロックに転送されません。代わりに、実行が終了し、これが出力ウィンドウに出力されます。
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled the distributed transaction
なんで?これらのエラーをキャッチ ブログに記録する必要があります。