我有一个链接服务器(SQL Server 14.0.1000.169)。本地服务器(SQL Server 10.0.1600)在短时间内(大约每分钟1个新行)接收数据到Table46
中。我需要将此新行的一些信息传递给链接服务器,因此我在本地服务器中为此创建了一个触发器:
CREATE TRIGGER New_Event
ON dbo.Table46 FOR INSERT AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [LinkedServer].[Database].[dbo].[TableEvents]
SELECT i.[046_ID] AS [id]
, NP.NoPart + ' ' + CONVERT(VARCHAR(3), T41.[041_No]) AS [name]
, DATEADD(MINUTE, -1 * i.[046_ExeTime], i.[046_DateTime]) AS [eventstart]
, i.[046_DateTime] AS [eventend]
, i.[046_IDRes] AS [resource_id]
, i.[046_ExeTime] AS [execution]
, ISNULL(MIN(T48.[048_MachTime]), 0) AS [same]
, ISNULL(MIN(T48_1.[048_MachTime]), 0) AS [all]
, i.[046_Pallet] AS [pallet]
FROM inserted AS i
INNER JOIN Table41 AS T41
ON i.[046_IDOp] = T41.[041_IDOp]
INNER JOIN NoParts AS NP
ON T41.[041_IDNoPart] = NP.Autonumber
INNER JOIN Table48 AS T48
ON i.[046_IDRes] = T48.[048_IDRes]
AND i.[046_IDOp] = T48.[048_IDOp]
INNER JOIN Table48 AS T48_1
ON i.[046_IDOp] = T48_1.[048_IDOp]
GROUP BY i.[046_ID], NP.NoPart, T41.[041_No], i.[046_MachTime],
i.[046_DateTime], i.[046_IDRes], i.[046_ExeTime], i.[046_Pallet];
END;
INSERT INTO
之后的原始查询,由于触发,我刚刚将Table46
虚拟表的inserted
更改了。
编辑1:
如果手动将新行添加到Table46
,则会出现以下错误(已经启动MSDTC服务):
OLE DB provider "SQLNCLI10" for linked server "[LinkedServer]" returned message "The partner transaction manager has disabled its support for remote/network transactions.".
Msg 7391, Level 16, State 2, Procedure New_Event, Line 5 [Batch Start Line 15]
The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "[LinkedServer]" was unable to begin a distributed transaction.
编辑2:
我遵循了these instructions,并且还允许两台服务器的防火墙中都有MSDTC入站规则,但是现在,如果我尝试添加该行,则查询需要花费很多时间执行,但尚未完成。对SELECT
的Table46
查询也发生了同样的情况。
如果触发器不起作用,每当Table46
收到新行时,还有什么其他方法可以插入远程服务器?
正如我的评论中提到的,您需要配置MSDTC以在两个链接的SQL服务器之间启用分布式事务。
如果您不想这样做,则可以在源表上使用触发器,以将所需的数据保存在'队列'表中。然后,您可以让一个单独的应用程序轮询队列表,获取数据并将其插入到链接服务器上的单独连接上(从而分开进行事务处理)。这种方法看似次优,但确实有一个优点:如果链接服务器不可用或速度较慢,则源服务器将继续全速运行,并且不会丢失任何数据。
实现第二种方法的一种方法是使用SQL Server代理。在触发器中,将必要的数据发送到消息队列。在接收(链接的)服务器上,处理消息并将数据插入TableEvents
。 SQL Server Broker在断开两个服务器的耦合的同时,始终确保事务完整性,而无需在两个服务器之间使用MSDTC。