涉及链接服务器的查询在没有使用或不需要事务时引发分布式事务错误

Query Involving Linked Server Raises Distributed Transaction Error When No Transaction is Used or Needed

我有一个多线程调度程序进程 (.NET),它调用需要从链接服务器提取数据并最终将数据插入本地 table 的存储过程。我没有明确使用任何事务——我不关心进程失败,因为我可以重新运行。此外,我想避免分布式事务(MSDTC)的复杂化。

我 运行 的是,大部分时间通过 .NET 过程,我收到以下错误:

The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "XXXX" was unable to begin a distributed transaction.
OLE DB provider "SQLNCLI11" for linked server "XXXX" returned message "No transaction is active.

当我从 SQL Server Management Studio 执行存储过程时,它没有收到错误。我一直在尝试追踪 SSMS 执行与 .NET 的不同之处,并且我发现一些实例是 .NET 进程没有收到错误。但即便如此,我也无法区分何时失败与何时失败。

为了它的价值,我在过程中放置​​了一些日志记录 @@trancount,它总是注册为 2。我可以理解一个隐式事务来覆盖 INSERT 语句以保存日志,但我无法解释第二个。对于它的价值,我的存储过程实际上调用了访问链接服务器的第二个过程——不确定这是否相关。综上所述,@@trancount returns 2 即使成功(无论是从 SSMS 还是 .NET 调用)。

DBA 已更改链接服务器属性以确保 "enable promotion of distributed transactions" 为假。我还应该尝试什么?谢谢!

我首先发现了导致交易尝试的原因(这是我的目标,因为我不需要交易)。从链接服务器中提取数据的过程是使用 SELECT ... INTO #temp 模式将该数据插入到 #temp table 中。由于它所选择的 table 是跨链接服务器的,我相信它也在那里创建了临时文件 table。要么,要么它仍在本地创建临时 table,但由于所选 table 跨链接服务器,它试图扩展事务(隐式插入语句)以覆盖本地和链接服务器。

无论哪种方式,当我更改为在 INSERT ... SELECT 语句之前的单独语句中创建临时 table 时,它都没有错误!

这没有向我解释为什么该过程会起作用(每次通过 SSMS,很少通过 .NET)。我将以某种方式将其归因于不同的执行计划......和 ​​SQL 服务器巫毒魔法。