【发布时间】:2015-10-06 15:39:46
【问题描述】:
我有两个数据库A 和B。它们都存储在一个数据库实例上。我在实例上创建了一个环回链接服务器。
数据库A 包含一个表dbo.Users 和一个更新dbo.Users 表的存储过程。在数据库B 我有一个查询,它做了两件事:
- 从数据库
A执行存储过程,更新dbo.Users表。 - 通过链接服务器从
dbo.Users中选择数据。
BEGIN TRANSACTION
EXEC [LinkedServer].A.dbo.UpdateUser
select * from [LinkedServer].A.dbo.Users
ROLLBACK TRANSACTION
当我尝试执行此存储过程时,仅当我在链接服务器上设置超时时才会出现以下异常;在其他情况下,查询不会完成:
Msg 3971, Level 16, State 1, Line 1 The server failed to resume the transaction. Desc:3900000002.
这个问题的原因是[LinkedServer].A.dbo.UpdateUser 存储过程的执行创建了一个不允许进行选择语句的事务。
所以我决定添加WITH (NOLOCK)如下:
BEGIN TRANSACTION
EXEC [LinkedServer].A.dbo.UpdateUser
select * from [LinkedServer].A.dbo.Users WITH (NOLOCK)
ROLLBACK TRANSACTION
然后我得到这个异常:
链接服务器“LinkedServer”的 OLE DB 提供程序“SQLNCLI11” 返回消息“未指定的错误”。
OLE DB 提供程序“SQLNCLI11”用于 链接服务器“LinkedServer”返回消息“查询超时 已过期”。
消息 7311,级别 16,状态 2,行 4 无法获取架构 OLE DB 提供程序“SQLNCLI11”的行集“DBSCHEMA_TABLES_INFO” 链接服务器“LinkedServer”。提供者支持该接口,但 使用时返回失败码。
我在microsoft support page 上找到了有关此异常的信息。有信息表明,当您尝试从 64 位 SQL Server 客户端运行分布式查询到链接的 32 位 SQL Server 时,会发生此错误。就我而言,这没有意义,因为我有一个环回链接服务器。
当数据库部署在单独的 SQL 服务器实例上时,不会发生上述错误。任何想法如何在使用环回链接服务器时省略锁或更改 T-SQL 以不出现异常?
【问题讨论】:
-
真的需要自引用链接服务器吗?为什么不通过
database_name.schema_name.table_name引用其他数据库? -
@TT 对于开发我们只有一台服务器,但在生产中它是两台不同的服务器。项目数据库引用$(RemoteServerToA),它可能引用自身,也可能不引用。
-
您确定 B 中的存储过程不通过链接服务器引用 B 中的表吗?
标签: sql-server sql-server-2012 linked-server self-reference