0

我有一个 SSIS 包,我手动执行以进行测试。当我这样做时,会发生错误(见下图)。但首先让我解释一下包中发生了什么:只有数据流本身。在那里我查询一个视图(OLE DB 源),它将为我提供下一步所需的参数。然后箭头指向 OLE DB 命令,在该命令中,我在本地 DB 服务器上执行存储过程并交出参数。这个 SP 是我的包装器,其中发生了 3 件主要事情: 1. SET XACT_ABORT ON;(稍后我们将需要它用于分布式事务) 2. 调用一个助手 SP,它将为我的远程目标表创建一个新的同义词。(这会创建一个类似 MY_REMOTE_TABLE 的同义词,当它创建时我可以毫无问题地手动查询它) 3. 调用将执行主要任务的助手 SP。这个助手 SP 有一个 BEGIN DISTRIBUTED TRANSACTION。在那里,我将本地数据库中的一些记录插入到 MY_REMOTE_TABLE 中。现在我直接在 BEGIN DISTRIBUTED TRANSACTION 之前和之后放置了一个日志条目,但是在我的日志中只有我在事务开始之前打印的条目。因此,一旦它打开分布式事务,它看起来就会失败。下图显示了我从 SSIS 得到的错误,但我不知道该怎么做。任何想法都非常感谢!下图显示了我从 SSIS 得到的错误,但我不知道该怎么做。任何想法都非常感谢!下图显示了我从 SSIS 得到的错误,但我不知道该怎么做。任何想法都非常感谢!

SSIS 错误消息

错误:SSIS 错误代码 DTS_E_OLEDBERROR。发生 OLE DB 错误。错误代码:0x80040E14。OLE DB 记录可用。来源:“Microsoft OLE DB Provider for SQL Server”Hresult:0x80040E14 描述:“Microsoft 分布式事务协调器 (MS DTC) 已取消分布式事务”错误:SSIS 错误代码 DTS_E_INDUCEDTRANSFORMFAILUREONERROR。“输入“OLE DB 命令输入”(140)”失败,因为发生错误代码 0xC020906E,并且“输入“OLE DB 命令输入”(140)”上的错误行处理指定错误失败。指定组件的指定对象发生错误。在此之前可能会发布错误消息,其中包含有关失败的更多信息。错误:SSIS 错误代码 DTS_E_PROCESSINPUTFAILED。

BEGIN TRY
  BEGIN DISTRIBUTED TRANSACTION 
  -- do my stuff here

  IF (@@TRANCOUNT > 0 AND XACT_STATE() = 1)
  BEGIN
    COMMIT TRANSACTION 
  END

  IF @Output_on = 1
    EXEC sp_write_to_log 'End of DISTRIBUTED TRANSACTION!';

END TRY
BEGIN CATCH
  IF (@@TRANCOUNT > 0 AND XACT_STATE() = -1)        
    ROLLBACK TRANSACTION
    INSERT INTO my_error_log (Time, Source, MSG, MSG_NR, Line_Nr) 
    VALUES (GETDATE(), ERROR_PROCEDURE() , ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_LINE());

    IF @Output_on = 1
      EXEC sp_write_to_log 'Error in DISTRIBUTED TRANSACTION!';

END CATCH;
4

1 回答 1

0

确保在您的本地计算机上启用了 MSDTC

  • 转到开始菜单 > 运行
  • 在命令提示符下键入 dcomcnfg 并按 Enter。将弹出组件服务窗口。
  • 展开组件服务,右键单击我的电脑并选择启动 MSDTC

还可以通过在 SQL Server Management Studio 查询窗口本身中执行 Helper SP 来进行验证。

使用 TRY...CATCH 处理事务块中的错误(BEGIN TRAN ... COMMIT)

SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRANSACTION;
        /*******...YOUR QUERY HERE eg. DELETE FROM customer..*******/           
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- retrieve error information
        SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_LINE () AS ErrorLine
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF (XACT_STATE()) = -1 --uncommittable transaction state.
    BEGIN
        SELECT
            N'The transaction is in an uncommittable state.' +
            'Rolling back transaction.'
        ROLLBACK TRANSACTION;
    END;

    IF (XACT_STATE()) = 1 --committabletransaction state
    BEGIN
        SELECT
            N'The transaction is committable.' +
            'Committing transaction.'
        COMMIT TRANSACTION;   
    END;
END CATCH;
GO
于 2013-07-02T12:33:52.210 回答