Sql server 带有即时更新的事务性复制—发布服务器触发器在即时更新时触发,或不复制其修改

Sql server 带有即时更新的事务性复制—发布服务器触发器在即时更新时触发,或不复制其修改,sql-server,Sql Server,我配置了一个发布服务器和多个订阅服务器,用于即时更新的事务性复制。我有两个复制的表,MyTable和MyTableHistory。我有一个“不用于复制”触发器,它捕获MyTable更改的历史记录,并将它们放在MyTableHistory表中。我的问题是: 如果我尝试仅在发布服务器上放置触发器: 当用户更新订阅服务器上的MyTable时,将立即通过分布式事务和Microsoft的存储过程在发布服务器上创建记录,并触发“立即更新”类型的复制。这将在发布服务器上触发触发器,从而按预期在发布服务器上创建

我配置了一个发布服务器和多个订阅服务器,用于即时更新的事务性复制。我有两个复制的表,MyTable和MyTableHistory。我有一个“不用于复制”触发器,它捕获MyTable更改的历史记录,并将它们放在MyTableHistory表中。我的问题是:

如果我尝试仅在发布服务器上放置触发器: 当用户更新订阅服务器上的MyTable时,将立即通过分布式事务和Microsoft的存储过程在发布服务器上创建记录,并触发“立即更新”类型的复制。这将在发布服务器上触发触发器,从而按预期在发布服务器上创建历史记录。但是,触发器刚刚创建的历史记录不会复制回订阅服务器。我猜这是它们阻止将已经复制的记录复制回发起它们的订阅者的副作用

如果我试图在发布者和订阅者身上同时放置触发器: 当用户更新订阅服务器上的MyTable时,会立即在发布服务器上创建记录,从而触发触发器并生成重复的历史记录。无论我做了什么尝试,我都不知道如何让触发器检测到复制的“立即更新”正在修改记录,因此它应该中止。我尝试过“不用于复制”和“sp\u检查\u是否用于同步\u触发器”,但我了解到这些并不是为了检测我要查找的内容


我认为上面两个选项中的第一个是首选的,但在这一点上,我愿意接受任何能使上面两个选项之一起作用的方法。有什么想法吗?谢谢

我找到的最佳解决方案是在发布服务器和订阅服务器上同时放置触发器,并在触发器中包含以下代码,以便在某些情况下避免在复制维护期间触发触发器。它需要以下三种方法:

  • 不适用于复制触发器选项-防止订阅服务器触发器触发 将记录从发布服务器复制到订阅服务器时
  • spGetLastCommand-这是我用它创建的一个签名存储过程 查看服务器状态权限。它返回最后一个命令,这样我们就可以 检查是否是在上运行的复制存储过程 publisher,这样我们就可以防止publisher触发器在 订阅服务器更改会立即更新发布服务器
  • sp_check_for_sync_触发器-此代码防止触发器 在复制过程中发出update语句时触发 存储过程正在尝试更新ms_repl_tran列
  • 希望这能帮助别人。但可能不会,因为我们是地球上最后一个使用这种复制方式的人;)


    我不确定您会在这里得到答案,因为SQL 2008不推荐使用事务性复制的可更新订阅。使您现在可能成为世界上最重要的这方面的专家:)
    declare @last_command nvarchar(512)
    exec master..spGetLastCommand @last_command output
    if @last_command like '%sp_MSsync_%_MyTable_1%' begin
        return
    end
    
    declare @table_id int = object_id('MyTable')
    declare @trigger_op varchar(max)
    declare @retcode int
    exec @retcode = sp_check_for_sync_trigger @table_id, @trigger_op output, @fonpublisher=1
    if @retcode = 1 begin
        return
    end
    exec @retcode = sp_check_for_sync_trigger @table_id, @trigger_op output, @fonpublisher=0
    if @retcode = 1 begin
        return
    end";