我有两个数据库A
和B
。它们都存储在一个数据库实例中。我在实例上创建了一个环回链接的服务器。
数据库A
包含一个表dbo.Users
和一个更新dbo.Users
表的存储过程。在数据库B
我有一个查询做两件事:
- 从数据库
- 选择
dbo.Users
通过链接服务器的数据
A
执行更新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
存储过程的执行创建了一个不允许执行select语句的事务。
所以我决定添加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 "返回消息"查询超时过期"。
Msg 7311, Level 16, State 2, Line 4无法获取schema为OLE DB提供程序"SQLNCLI11"提供行集"DBSCHEMA_TABLES_INFO"链接服务器"LinkedServer"。提供程序支持接口,但是使用时返回失败代码。
我在微软支持页面上找到了有关此异常的信息。有信息表明,当您尝试从64位SQL Server客户端向链接的32位SQL Server运行分布式查询时,会发生此错误。在我的情况下,这没有意义,因为我有一个环回链接的服务器。
当数据库部署在单独的SQL server实例上时,不会发生上述错误。在使用环回链接的服务器时,如何省略锁或更改T-SQL以避免出现异常?
链接服务器" LinkedServer "的OLE DB提供程序"SQLNCLI11"返回消息"Unspecified error".
链接服务器" LinkedServer "的OLE DB提供程序"SQLNCLI11"返回消息"Query timeout expired".
Msg 7311, Level 16, State 2, Line 4无法获取schema行集"DBSCHEMA_TABLES_INFO"用于OLE DB提供程序"SQLNCLI11"用于链接服务器"LinkedServer"。提供程序支持接口,但是使用时返回失败代码。
我也遇到过上述错误。
如果你正在做循环回链接服务器并收到相同的错误,然后检查使用循环回服务器的任何SP应该在脚本末尾写入(创建过程)。
如果使用TFS中的代码,则在部署后使用循环链接服务器编写该SP的创建过程语句。
只需遵循以下任何一个步骤:-
- 复制粘贴SP到脚本末尾。或
- 不要使用环回服务器。或
- 如果您使用从TFS发布脚本在部署后脚本中写入SP(在数据插入到所有表之后)