2

我用谷歌搜索了很多,并反复偶然发现一些让我感觉的文章——这行不通!

根据此链接 https://docs.microsoft.com/en-us/sql/integration-services/extending-packages-scripting/data-flow-script-component/connecting-to-data-sources-in-the-脚本组件?视图=sql-server-2014

在脚本组件中编写托管代码时,不能调用返回非托管对象的连接管理器的 AcquireConnection 方法,例如 OLE DB 连接管理器和 Excel 连接管理器。但是,您可以读取这些连接管理器的 ConnectionString 属性,并使用 System.Data.OleDb 命名空间中的 OLEDB 连接的连接字符串直接在代码中连接到数据源。

而且我相信,如果我不能调用 Acquire Connection,那么我就不能参与组件容器在 SSIS 包中启动的事务。

我现有的 SSIS 包使用 OLEDB 连接管理器(本机),我的自定义组件将使用相同的连接管理器。目前,我正在使用连接字符串而不调用 Acquire Connection - 在这种方法中,由于我正在创建一个新连接,因此组件无法参与父 SSIS 序列容器可能已经启动的任何事务,而这反过来又不会如果下游发生故障,导致自定义组件所做的更改回滚。由于巨大的影响,将现有的连接管理器更改为 ADO.NET 看起来并不可行,因为现有的 OleDb 连接管理器用于许多 OleDb 组件,如现有代码中的 OleDb 目标。

有什么办法可以解决这个问题 - 所以基本上我想让事务在自定义组件中使用 OleDb 连接管理器工作?

4

1 回答 1

2

好吧,DbConnection及其派生类SqlConnection具有方法EnlistTransaction,它允许将此连接添加(登记)到分布式事务中。请注意,这是由 MS DTC 管理的分布式事务,而不是本机 MS SQL 事务。
理论上(在这种特定情况下我从未这样做过),您可以根据从 OLE DB 连接管理器派生的连接字符串打开托管连接,并将其登记到事务中。在开发中寻找和检查的东西:

  • 安装、配置并确保 MS DTC 正常工作并且可由运行包的服务器和数据库服务器访问。
  • 如果包中没有分布式事务(当TransactionSupport <> Required),事务参数将为null。您也应该在代码中处理这种情况。
  • Transaction参数 inAquireConnection具有 type object,文档说它是分布式事务的句柄。我会在输入AquireConnection方法时直接做一个断点并检查它的真实结构;您需要将其转换为System.Transactions.Transaction类型。
  • 您可以尝试通过调用来获取环境分布式事务System.Transactions.Transaction.Current。也许,它可能会奏效。

请更新您的结果。

于 2020-07-22T11:04:53.617 回答