与环回链接服务器的事务 - 锁定问题

Transaction with loopback linked server - locking issues

我有两个数据库 AB。它们都存储在一个数据库实例上。我在实例上创建了一个环回链接服务器。

数据库A包含一个tabledbo.Users和一个存储过程更新dbo.Userstable。在数据库 B 中,我有一个查询做两件事:

  1. 从数据库 A 执行存储过程,更新 dbo.Users table.
  2. Select 数据来自 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

然后我得到这个异常:

OLE DB provider "SQLNCLI11" for linked server " LinkedServer " returned message "Unspecified error".
OLE DB provider "SQLNCLI11" for linked server " LinkedServer " returned message "Query timeout expired".
Msg 7311, Level 16, State 2, Line 4 Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI11" for linked server "LinkedServer". The provider supports the interface, but returns a failure code when it is used.

我在 microsoft support page 上找到了有关此异常的信息。有信息表明,当您尝试 运行 从 64 位 SQL 服务器客户端向链接的 32 位 SQL 服务器分发查询时,会发生此错误。在我的例子中,这没有意义,因为我有一个环回链接服务器。

当数据库部署在单独的 SQL 服务器实例上时,不会发生上述错误。任何想法如何省略锁或更改 T-SQL 以在使用环回链接服务器时不获取异常?

OLE DB provider "SQLNCLI11" for linked server " LinkedServer " returned message "Unspecified error".

OLE DB provider "SQLNCLI11" for linked server " LinkedServer " returned message "Query timeout expired".

Msg 7311, Level 16, State 2, Line 4 Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI11" for linked server "LinkedServer". The provider supports the interface, but returns a failure code when it is used.

我也遇到了上面提到的错误。

如果您正在执行环回链接服务器并收到相同的错误,请检查是否应在脚本末尾写入任何使用环回服务器的 SP(创建过程)。

如果使用来自 TFS 的代码,请在 post 部署中使用环回链接服务器编写该 SP 的创建过程语句。

只需按照以下任一步骤操作即可:-

  1. 复制粘贴SP到脚本末尾。
  2. 不要使用环回服务器。
  3. 如果您正在使用 来自 TFS 的发布脚本 在 Post 部署脚本中写入 SP(在数据插入所有 table 之后)。

这些解决方案对我有用。