我无法理解链接服务器的情况。
所以我们有一个从 2008R2 服务器到 2014 服务器的链接服务器。下面的示例查询是从 2008R2 服务器执行的,它工作正常。
SET XACT_ABORT ON;
Declare @BatchSize int = 10
DELETE from LINKEDSRV.DB.DBO.Table
INSERT INTO LINKEDSRV.DB.DBO.Table (ECN)
SELECT TOP (10) C1 from LINKEDSRV.DB.DBO.Table22 --order by C1
SELECT * FROM LINKEDSRV.DB.DBO.Table
但是当我用它执行相同的事情时,order by C1
它不会返回任何结果。
第二种情况 - 如果我替换TOP(10)
withTOP(@BatchSize)
并且 noorder by
我也没有得到任何结果。例如
SELECT TOP (@BatchSize) C1 from LINKEDSRV.DB.DBO.Table22
如果我SET XACT_ABORT OFF
. 那么 XACT_ABORT 在链接服务器方面是否有任何限制?
编辑- 做了更多的测试,看起来它也与行数有关
可能的回购
在服务器 A 上
use testdb
go
create table t1( c1 int, c2 datetime)
create table t2( c1 int, c2 datetime)
insert into t2 select 1, GETDATE()
insert into t2 select * from t2 -- insert close to 5000 rows, I found the issue around over around 35000 rows
在服务器 B
创建到 ServerA 的链接服务器
SET XACT_ABORT ON;
Declare @BatchSize int = 10
delete from ServerA.testdb.dbo.t1
insert into ServerA.testdb.dbo.t1 (c1)
select top (@BatchSize) c1 from ServerA.testdb.dbo.t2 --order by c2
select * from ServerA.testdb.dbo.t1
没有输出。但是,如果您将表 t2 中的行数减少到 2000 左右,它就可以正常工作。
的设置
XACT_ABORT
传播到远程 SQL Server,如处理服务器到服务器远程存储过程中的错误中所述。如分布式查询和分布式事务中所述,该设置还会影响是否可以更新以及如何处理它们。你
INSERT
是允许的,XACT_ABORT OFF
因为 SQL Server 支持嵌套事务。然而,似乎存在一个实现错误,因为在插入期间跟踪 2014 服务器上的活动显示当 SQL Server 尝试释放架构锁时发生错误:
此错误中止远程服务器上的语句(尝试释放模式锁),但当
XACT_ABORT
is时OFF
,远程服务器继续处理下一条语句。尽管模式锁定释放错误,插入仍完成。当
XACT_ABORT
isON
时,整个远程批处理被中止,因此插入被回滚。我能够在本地重现您的问题,但该
ORDER BY
条款并不重要。您可以通过多种方式避免该问题,包括将 包装
INSERT
在显式事务中(假设您可以使用 DTC)。我建议您避免远程更改的四部分名称语法,因为实现是基于游标模型的。您通常会使用批量方法获得更好的性能,或者通过在远程服务器上拉取数据(而不是从本地服务器推送数据)。
查看相关问答哪个更高效:从链接服务器中选择还是插入链接服务器?
根据我的经验,通过链接服务器执行多部分命令通常会遇到问题,尤其是当表很大时。尝试这个 :