与环回链接服务器的事务 - 锁定问题
Transaction with loopback linked server - locking issues
我有两个数据库 A
和 B
。它们都存储在一个数据库实例上。我在实例上创建了一个环回链接服务器。
数据库A
包含一个tabledbo.Users
和一个存储过程更新dbo.Users
table。在数据库 B
中,我有一个查询做两件事:
- 从数据库
A
执行存储过程,更新 dbo.Users
table.
- 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 的创建过程语句。
只需按照以下任一步骤操作即可:-
- 复制粘贴SP到脚本末尾。 或
- 不要使用环回服务器。 或
- 如果您正在使用 来自 TFS 的发布脚本 在 Post 部署脚本中写入 SP(在数据插入所有 table 之后)。
这些解决方案对我有用。
我有两个数据库 A
和 B
。它们都存储在一个数据库实例上。我在实例上创建了一个环回链接服务器。
数据库A
包含一个tabledbo.Users
和一个存储过程更新dbo.Users
table。在数据库 B
中,我有一个查询做两件事:
- 从数据库
A
执行存储过程,更新dbo.Users
table. - 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 的创建过程语句。
只需按照以下任一步骤操作即可:-
- 复制粘贴SP到脚本末尾。 或
- 不要使用环回服务器。 或
- 如果您正在使用 来自 TFS 的发布脚本 在 Post 部署脚本中写入 SP(在数据插入所有 table 之后)。
这些解决方案对我有用。