• 事务复制中的msrepl_ccs


    在事务复制里,如果一个article被更新,distributionagent会调用相应的存储过程将数据更新到订阅端。 这些存储过程分别是[sp_MSins_dboTableName][sp_MSdel_dboTableName] [sp_MSupd_dboTableName] 分别对应插入,删除和更新操作。这些存储过程是在快照初始化时创建的。不过您可能曾经观察到还有其它两个存储过程被调用过:sp_MSins_dboTableName_msrepl_ccs,sp_MSdel_dboTableName_msrepl_ccs

    那么两个存储过程的作用是什么呢?

       

    sp_addpublication 的参数sync_method值为concurrent时,生成快照时article是允许被更新的,这些更新随后也会被应用到订阅端。 如果是使用默认的命令去更新,那么就可能遇到下面的情况:

    假设表ta有2行数据,snapshot agent已经读取第一行和第二行数据,这时插入了第三条数据。接下来snapshot会去读第三条数据,并将三行数据打包到bcp文件中。而第三条数据的日志也会被logreader传递到分发。 这样就会产生一个问题:如果仍然使用sp_MSins_dboTableName,就会造成主键冲突,出现1033错误:Violation of %ls constraint '%.*ls'. Cannot insert duplicate key in object '%.*ls'. The duplicate key value is %ls. 

       

    为了避免这种情况,设计出了另外两种存储过程(存储过程的定义请见文章结尾):

    当操作是更新时,先判断改行是否存在,如果存在,则使用更新操作。

    如果是删除操作,即使影响行为0,也不会抛出20598错误The row was not found at the Subscriber when applying the replicated command

    如果是更新操作,则会先调用css的删除操作,然后调用css的插入命令,以避免20598错误。

    所以在初始化的阶段,你会看到多出了两种存储过程。不过在初始化完成后,这两个存储过程就会从订阅段删除掉。

       

    下面列出了三个命令的调用截图。 请注意,这类msrepl_ccs的类型有别于普通的存储过程,其值为-2147483618。

       

    插入操作。sp_MSins_dboTableName会被解释成sp_MSins_dboTableName_msrepl_ccs

       

       

    更新操作。sp_MSupd_dboTableName会分解为两个操作,现将数据删除,然后插入新的数据。

       

       

       

       

     删除操作。sp_MSdel_dboTableName会被解释成sp_MSdel_dboTableName_msrepl_ccs

       

       

    存储过程的定义

    create procedure [dbo].[sp_MSins_dbota_msrepl_ccs]

    @c1 int,

    @c2 int

    as

    begin

    if exists (select *

                 from [dbo].[ta]

                where [id] = @c1)---------在普通的存储过程中,是没有这段判断逻辑的。

    begin

    update [dbo].[ta] set

    [c] = @c2

    where [id] = @c1

    end

    else

    begin

    insert into [dbo].[ta](

    [id],

    [c]

    ) values (

        @c1,

        @c2    )

    end

    end

    go

    create procedure [dbo].[sp_MSdel_dbota_msrepl_ccs]

    @pkc1 int

    as

    begin 

    delete [dbo].[ta]

    where [id] = @pkc1

    ---------在普通的存储过程中,还有一段额外的逻辑: 如果影响行为0,则抛出异常。

    end 

    go

       

       

       

       

    一段删除的记录

       

  • 相关阅读:
    微信小程序 获取手机号 获取基础信息 自定义分享 获取dom节点
    微信公众号 生成带参数进入公众号关注页的二维码 监听用户关注公众号事件 自定义菜单栏 (服务端)
    js 防抖和节流 (学习笔记)
    vue 封装axios api模块化 并使用方式 MD5 数据加密
    1.1 Logistics Regression模型
    音视频入门-19-使用giflib处理GIF图片
    思维
    面试题库
    前端代码规范
    D3JS笔记
  • 原文地址:https://www.cnblogs.com/stswordman/p/3227820.html
Copyright © 2020-2023  润新知