另一个会话正在使用的事务上下文

时间:2012-05-22 14:54:25

标签: tsql triggers sql-server-2008-r2 linked-server

我有一个名为MyTable的表,我在其上定义了一个触发器,如下所示:

CREATE TRIGGER dbo.trg_Ins_MyTable
   ON  dbo.MyTable 
   FOR INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    insert SomeLinkedSrv.Catalog.dbo.OtherTable 
        (MyTableId, IsProcessing, ModifiedOn)
    values (-1, 0, GETUTCDATE())
END
GO

每当我尝试在MyTable中插入一行时,都会收到以下错误消息:

  

Msg 3910,Level 16,State 2,Line 1   另一个会话正在使用的事务上下文。

我已将SomeLinkedSrv正确定义为链接服务器(例如,select * from SomeLinkedSrv.Catalog.dbo.OtherTable工作正常)。

如何避免错误并成功插入记录+执行触发器?

8 个答案:

答案 0 :(得分:17)

如果启用了MARS,则无法在分布式事务中使用环回链接服务器。

  

环回链接服务器不能在分布式事务中使用。   尝试针对环回链接服务器的分布式查询   在分布式事务中导致错误,例如错误3910:   “[Microsoft] [ODBC SQL Server驱动程序] [SQL Server]事务上下文中   另一个会话使用。“这个限制不适用于   INSERT ... EXECUTE语句,由没有的连接发出   启用多个活动结果集(MARS),针对a执行   环回链接服务器。请注意,限制仍然适用于   MARS已在连接上启用。

http://msdn.microsoft.com/en-us/library/ms188716(SQL.105).aspx

答案 1 :(得分:1)

我解决了。 我使用相同的链接服务器来调用第二个过程,然后进入我使用相同链接服务器的过程。

这很容易,只有我们必须知道链接服务器的限制。

答案 2 :(得分:1)

这种情况的原因之一是适用于链接服务器数据库表的触发器。处理数据库问题的SQL Server的另一个SQL版本很重要。为避免在sql查询执行过程中发生此错误,我们应暂时禁用表,并在执行后为更新的表启用触发器。全部带有数据库名称检查。这是一个示例:

     Select * From People  where PersonId In (@PersonId, @PersonIdRight)
     IF 'DOUBLE' = DB_NAME()
        ALTER TABLE [dbo].[PeopleSites] DISABLE TRIGGER [PeopleSites_ENTDB_UPDATE]

     Update PeopleSites Set PersonId = @PersonIdRight Where  PersonId = @PersonId

     IF 'DOUBLE' = DB_NAME()
        ALTER TABLE [dbo].[PeopleSites] ENABLE TRIGGER [PeopleSites_ENTDB_UPDATE]


     Select * From PeopleSites where PersonId In (@PersonId, @PersonIdRight)

答案 3 :(得分:0)

我在DEV environemnt中也遇到了同样的错误,将链接数据库移动到另一个sql实例解决了这个问题。在我们的生产环境中,这些数据库已经在不同的实例上

答案 4 :(得分:0)

在我的情况下,我使用的是SQL 2005,并且在另一个会话中使用了#34;事务上下文"在链接服务器上运行Insert .... exec时。我的修复是从SP2 build 3161到SP3。 SP2累积5应该可以修复。

https://support.microsoft.com/en-us/kb/947486

答案 5 :(得分:0)

当远程数据库位于同一服务器上时,配置链接服务器而不指定数据库服务器ip / hostname和port。只需数据库名称即可。

答案 6 :(得分:0)

我通过删除存储过程中使用的链接服务器然后通过相同的链接服务器调用存储过程来解决它。它没有在DEV environement工作。

答案 7 :(得分:0)

尝试运行UPDATE查询时,我得到了相同的“另一个会话正在使用事务上下文”:

 BEGIN      TRAN
--ROLLBACK  TRAN
--COMMIT    TRAN
UPDATE  did 
SET     did.IsProcessed = 0,
        did.ProcessingLockID = NULL
FROM    [proddb\production].DLP.dbo.tbl_DLPID did (NOLOCK)
WHERE   did.dlpid IN ('bunch of GUIDs')
--WHERE   did.DLPID IN (SELECT DLPID FROM @TableWithData)

但是我没有意识到我已经在尝试在ProdDb \ Production服务器上的DLP数据库上运行它。一旦我删除了“ [proddb \ production] .DLP.dbo”。查询中的前缀,效果很好。