在事务复制里,如果一个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

一段删除的记录

事务复制中的msrepl_ccs的更多相关文章

  1. 事务复制中的snapshot

        Snapshot agent读取article的信息,将article的内容和脚本放置到snapshot文件夹中: 接下来distribution agent会读取这些快照文件,传输到订阅,完 ...

  2. 解决服务器复制中SID冲突问题

    解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...

  3. MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用

    MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用 replicate-ignore-dbreplicate-wild-ignor ...

  4. Spring 下默认事务机制中@Transactional 无效的原因

    Spring中 @Transactional 注解的限制1. 同一个类中, 一个nan-transactional的方法去调用transactional的方法, 事务会失效 If you use (d ...

  5. 复制中的NOT FOR REPLICATION

    错误#1 10:51 2012-9-4sp_MSget_repl_commands 重复键插入解答#1 修改distribution库下sp_MSget_repl_commands 存储过程decla ...

  6. MySQL复制中slave延迟监控

    在MySQL复制环境中,我们通常只根据 Seconds_Behind_Master 的值来判断SLAVE的延迟.这么做大部分情况下尚可接受,但并不够准确,而应该考虑更多因素. 首先,我们先看下SLAV ...

  7. 关于MySQL主从复制中UUID的警告信息

    日期: 2014年5月23日 博客: 铁锚 最近在查看MariaDB主从复制服务器 Master 的错误日志时看到很多条警告信息,都是提示 UUID()函数不安全,可能 Slave 产生的值和 Mas ...

  8. 事务复制5: Transaction and Command

    事务复制使用 dbo.msrepl_transactions 和 dbo.MSrepl_commands 存储用于数据同步的Transaction和Command.在replication中,每个co ...

  9. SQLServer复制(二)--事务代理作业

    之前的一篇已经介绍了如何配置复制,介绍了发布者.分发者和订阅者以及事务日志运行的简单关系.其中提到了复制代理,我们这篇将详细介绍复制代理,它是什么?在事务复制的步骤中起到了什么作用? 代理和工作 首先 ...

随机推荐

  1. HTML入门的简单学习

    1:HTML简介    1.1:HTML(Haper Text Markup language):超文本标记语言    超文本就是指页面内可以包含图片,链接,甚至音乐,程序等非文字元素     1.2 ...

  2. Leetcode 303 Range Sum Query - Immutable

    题意:查询一个数组在(i,j]范围内的元素的和. 思路非常简单,做个预处理,打个表就好 拓展:可以使用树状数组来完成该统计,算法复杂度为(logn),该数据结构强力的地方是实现简单,而且能完成实时更新 ...

  3. 通过MSSQl作业定时执行批处理BAT文件

    前言 有些时候,我们可能会需要定时执行一下批处理来达到一定的目的,比如Oracle数据库的定时备份,当然Oracle也可以通过Rman实现定时备份.我们大多数的时候是通过操作系统的计划任务实现定时执行 ...

  4. Log4cpp介绍及使用

    Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能.使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流.内存字符串队列.文件.回滚文件.调试器.Wind ...

  5. android: SQLite创建数据库

    SQLite 是一款轻量级的关系型数据库,它的运算速度非常快, 占用资源很少,通常只需要几百 K 的内存就足够了,因而特别适合在移动设备上使用.SQLite 不仅支持标准的 SQL 语法,还遵循了数据 ...

  6. c#之第二课

    输出语句: /////////////////////////////// public class Hello1 { public static void Main() { System.Conso ...

  7. 深入学习golang(5)—接口

    接口 概述 如果说goroutine和channel是Go并发的两大基石,那么接口是Go语言编程中数据类型的关键.在Go语言的实际编程中,几乎所有的数据结构都围绕接口展开,接口是Go语言中所有数据结构 ...

  8. Android--使用Canvas绘图

    前言 除了使用已有的图片之外,Android应用常常需要在运行时根据场景动态生成2D图片,比如手机游戏,这就需要借助于Android2D绘图的支持.本篇博客主要讲解一下Android下使用Canvas ...

  9. Maven Learning - Direct Dependencies & Transitive Dependencies

    Dependencies declared in your project's pom.xml file often have their own dependencies. The main dep ...

  10. [转] js == 与 === 的区别

    1.对于string,number等基础类型,==和===是有区别的 1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等 2)同类型比较,直接进 ...