我有一个从ServerA连接到ServerB的链接服务器。在每个服务器中都有一个启动事务的SP,并且对于一个ServerA来说是必要的。SP将在ServerB.SP内执行。我的问题是,当这样做时,我得到错误:
EXECUTE后的事务计数表示BEGIN和COMMIT语句的数目不匹配。
我已经搜索了有关该错误的信息,但问题/答案不包括linkedServers。我就是为此而来的。代码是这样的,非常简单:
CREATE OR ALTER PROCEDURE #DB1_sp
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
EXEC [LinkedServer].[db].[Schema].[SP]
... params ...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END
EXEC [Logs].[SetError]
END CATCH
END
GO
EXEC #DB1_sp
在LinkedServer端,SP几乎是相同的代码。事实上,如果我们删除BEGIN TRANSACTION
,我的所有代码都可以工作,但由于初始验证,这不是一个选项。
我曾尝试查看DISTRIBUTED TRANSACTIONS
,SAVE TRANSACTIONS
和SET XACT_ABORT ON
等语句,所有这些都在顶部存储过程中(因为我无法访问/编辑内部SP),但它不起作用。
要在SQL Server或其他RDBMS的不同实例上使用事务,您必须在所有执行SQL Server的机器上激活MSDTC。这是已知的"两阶段承诺"。事务协调器将在与事务有关的所有服务器上启动投票阶段,如果一切正常,则将SQL COMMIT命令发送到所有机器。第二阶段包括在所有机器上应用有效的COMMIT…
但是如果一台机器在阶段1(投票)和阶段2(应用)之间崩溃了,那么转换将部分地提交到存活的机器上,而不是在这台机器上。
结果将是一个发现混乱,我祝你好运,整理有效的数据和不一致,恢复情况