我编写了一个小的自己的复制 - 一个触发 DTC INSERT 到另一台服务器的触发器(我自己的“复制”的一个原因:触发器运行时它计算一些数据,另一个:它从快速版本到快速版本)。
当我使用 Windows 身份验证从同一主机进行初始插入时,它工作正常。但是另一台主机上有一个网络服务器,它使用 sqlserver 登录(用于测试 sa)。当此主机执行初始插入时,在 DTCTransaction EventClass(Profiler)中的登记和创建阶段之后,我得到一个内部中止。
神奇的是:当我第一次使用 Windows 身份验证从同一主机启动它时,我可以从网络服务器启动它并且它工作正常。但我只需要等待几分钟,它不会起作用。
我的推理错误在哪里?
这是我的初始服务器脚本:
EXEC master.dbo.sp_addlinkedserver @server = @Servername, @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = @Servername, @locallogin = NULL , @useself = N'False', @rmtuser = @Serverlogin, @rmtpassword = @Serverpwd
更新:
我想将一些统计表从一个 sql server 导出到另一个 sql server。我写了同样的触发器来做到这一点。同时我在触发器中调用了一些额外的数据并将其写入第二个数据库,所以我不能使用标准复制。
我用这段代码创建了一个链接服务器:
EXEC master.dbo.sp_addlinkedserver @server = @Servername, @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = @Servername,@locallogin = NULL,@useself = N'False',@rmtuser = @Serverlogin,@rmtpassword = @Serverpwd
我的触发器如下所示:
CREATE TRIGGER <schema>.<name> ON <schema>.<table> AFTER INSERT, UPDATE
-- some code
SET xact_abort ON
BEGIN DISTRIBUTED TRANSACTION
-- calculate some additional data before insert
INSERT INTO <servername>.<database>.<schema>.<table> (<columns>) VALUES (<values>)
COMMIT TRANSACTION
RETURN
如果触发触发器的插入的发起者使用“windows authentification”,这将非常有用。
当我使用“sql server authentification”时出现我的问题,这是我们的 apache tomcat 网络服务器所必需的:
OLE DB provider "SQLNCLI10" for linked server "<server>" returned message "Login timeout expired".
OLE DB provider "SQLNCLI10" for linked server "<server>" returned message "A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.".
Could not open a connection to SQL Server [5].
当我查看 SQL Server Profiler 时,DTCTransaction EventClass 返回
7 - Enlisting in a DTC transaction
6 - Creating a new DTC transaction
10 - Internal abort
16 - Transaction is aborting
当我第一次运行“windows authentification”时,我可以在接下来的几分钟内成功执行插入“sql server authentification”。当我稍等一下时,会发生同样的错误。
所以我的第一个解决方案是将触发器更改为 WITH EXECUTE AS OWNER
Alter database <database> Set trustworthy ON
ALTER TRIGGER <schema>.<name> ON <schema>.<table> WITH EXECUTE AS OWNER AFTER INSERT, UPDATE
如果我使用“sql server authentification”从本地计算机运行插入,但不能从另一台服务器运行插入,则此方法有效。但它也应该在另一台服务器上工作。