Search code examples
sql-serverlinked-server

SQL Server linked server error "The partner transaction manager has disabled its support for remote/network transactions."


I have a linked server (SQL Server 14.0.1000.169). The local server (SQL Server 10.0.1600) receives data in short periods of time, around 1 new row per minute, into Table46. I need to pass some of the information of this new row to the linked server, so I created a trigger in the local server for this:

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;

The original query after the INSERT INTO works, I just changed Table46 for the inserted virtual table because of the trigger.

Edit 1:

If I add a new row manually to Table46 I get the following error (already started MSDTC service):

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.

Edit 2:

I have followed these instructions and also allowed MSDTC inbound rules in the Firewall of both servers but now if I try to add the row the query takes a lot of time executing, it hasn't finished yet. The same is happening with a SELECT query to Table46.

What are other ways to insert in the remote server whenever Table46 receives a new row, if triggers don't work?


Solution

  • As mentioned in my comment you need to configure MSDTC to enable distributed transactions between the two linked SQL servers.

    If you don't want to do that, then you can use a trigger on the source table to save the required data in a 'queue' table. Then you can have a separate application poll the queue table, fetch data and insert them on the linked server on separate connections (and thus separate transactions). This method may seem suboptimal but does have one advantage: if the linked server is unavailable or slow the source server continues to work at full speed and no data is ever lost.

    One way to implement the second approach is to use SQL Server broker. In the trigger send the necessary data to a message queue. On the receiving (linked) server process the messages and insert the data in TableEvents. SQL Server Broker ensures transactional integrity all the way without the use of MSDTC between the two servers while decoupling the two servers. Note that the servers no longer need to be linked anymore (unless you need them linked for some other reason)