我有一个多线程调度程序进程(.NET),它调用需要从链接服务器提取数据并最终将数据插入本地表的存储过程。我没有明确使用任何交易 - 我不关心流程失败,因为我可以重新运行。此外,我想避免分布式事务(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
即使成功也会返回2(无论是从SSMS还是.NET调用)。
DBA已更改链接服务器属性以确保“启用分布式事务的促销”为false。我还应该尝试什么?谢谢!
答案 0 :(得分:2)
我首先发现了导致交易尝试的原因(这是我的目标,因为我不需要交易)。从链接服务器提取数据的过程是使用SELECT ... INTO #temp
模式将该数据插入到#temp表中。由于它是从链接服务器中选择的表,我相信它也在那里创建临时表。或者它仍在本地创建临时表,但由于所选表是跨越链接服务器,因此它试图将事务扩展(隐式到insert语句)以覆盖本地和链接服务器。
无论哪种方式,当我更改为在INSERT ... SELECT
语句之前的单独语句中创建临时表时,它的运行没有错误!
这不能解释为什么程序可行(每次都通过SSMS,很少通过.NET)。我会以某种方式粉笔到不同的执行计划......以及SQL Server voodoo magic。