我在谷歌上搜索了很多,并反复偶然发现了一些文章,这些文章让我觉得 - 这行不通!
When you write managed code in a Script component, you cannot call the AcquireConnection method of connection managers that return unmanaged objects, such as the OLE DB connection manager and the Excel connection manager. However, you can read the ConnectionString property of these connection managers, and connect to the data source directly in your code by using the connection string of an OLEDB connection from the System.Data.OleDb namespace.
而且我相信,如果我无法调用Acquire Connection,那么我就无法参与组件容器在SSIS包中启动的事务。
我现有的 SSIS 包使用 OLEDB 连接管理器( native ),并且我的自定义组件将使用相同的连接管理器。目前,我正在使用连接字符串而不调用 Acquire Connection - 在这种方法中,因为我正在创建一个新连接,所以该组件无法参与父 SSIS 序列容器可能已启动的任何事务,而这反过来又不会如果下游发生故障,则导致回滚自定义组件所做的更改。由于影响巨大,将现有连接管理器更改为 ADO.NET 看起来并不可行,因为现有 OleDb 连接管理器在许多 OleDb 组件(例如现有代码中的 OleDb 目标)中使用。
有什么方法可以解决这个问题 - 所以基本上我想在自定义组件中使用 OleDb 连接管理器让事务正常工作?
最佳答案
嗯,DbConnection 及其派生 SqlConnection 类具有方法 EnlistTransaction
,它允许将此连接添加(登记)到分布式事务中。请注意,这是由 MS DTC 管理的分布式事务,而不是 native MS SQL 事务。
理论上(我从未在这种特定情况下这样做过),您可以根据从 OLE DB conn 管理器派生的连接字符串打开托管连接,并将其登记到事务中。在开发中需要寻找和检查的事情:
- 安装、配置并确保 MS DTC 正常工作并且可由运行程序包的服务器和数据库服务器访问。
- 如果包中没有分布式事务(当
TransactionSupport <> Required
时),事务参数将为null
。您也应该在代码中处理这种情况。 -
Transaction
AquireConnection
中的参数类型为object
,文档说它是分布式事务的句柄。我会在输入AquireConnection
时立即断点方法并检查其真实结构;您需要将其转换为System.Transactions.Transaction
类型。 - 您可以尝试通过调用
System.Transactions.Transaction.Current
来获取环境分布式事务。也许,它可能会起作用。
请更新您的结果。
关于sql-server - 在自定义 SSIS 数据流组件中使用 OleDb 连接管理器时的事务支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63030050/