具有即时更新的事务复制 - 发布者触发器在立即更新时触发,或者不复制其修改

时间:2018-06-08 20:11:01

标签: sql-server

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

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

如果我尝试将触发器同时放在发布商和订阅者身上: 当用户更新订户上的MyTable时,会立即在发布者上创建记录,该记录会触发触发器并生成重复的历史记录。无论我尝试过什么,我都无法弄清楚如何通过复制来检测记录是否被修改"立即更新"所以它应该中止。我已经尝试过#34;不是为了复制"和" sp_check_for_sync_trigger",但我了解到这些并不是为了检测我正在寻找的东西。

我认为上述两个选项中的第一个是首选,但在这一点上,我对任何可以使上述两个选项之一起作用的方法持开放态度。有任何想法吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我找到的最佳解决方案是将触发器放在发布者和订阅者身上,并在触发器中包含以下代码以在特定条件下保释,以避免在复制维护期间触发器触发。它需要以下三种方法:

  1. 不适用于复制触发器选项 - 防止触发订阅者触发器 何时将记录从发布者复制到订阅者
  2. spGetLastCommand - 这是我创建的签名存储过程 查看服务器状态权限。它返回最后一个命令,所以我们可以 检查是否是复制存储过程运行 发布商因此我们可以阻止发布者触发器何时触发 订阅者更改会立即更新发布者。
  3. sp_check_for_sync_trigger - 此代码可防止触发器发生 在复制时发出更新语句时触发 存储过程正在尝试更新ms_repl_tran列。
  4. 希望有人帮助。但可能不是因为我们是使用这种类型的复制在地球上的最后一个;)

    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";