Transaction Replication1:Subscription PK columns are readonly

在使用Transaction Replication时,Subscriber 端必须是Read Only的 , all data at the Subscriber is “read-only” (transactional replication does not enforce this at the Subscriber),不能更新Subscriber端的数据的主键,否则,某些数据更新操作会失败。

在Transaction Replication中,How Changes Are Propagated for Transactional Articles?

默认的是使用系统自动生成的存储过程来更新(delete,update,insert)数据的。

transactional replication should script out and subsequently call a stored procedure to propagate changes to Subscribers (the default).

By default, transactional replication propagates changes to Subscribers through a set of stored procedures that are installed on each Subscriber. When an insert, update or delete occurs on a table at the Publisher, the operation is translated into a call to a stored procedure at the Subscriber. The stored procedure accepts parameters that map to the columns in the table, allowing those columns to be changed at the Subscriber.

Default stored procedures

The three procedures that replication creates by default for each table article are:

  • sp_MSins_< tablename >, which handles inserts.
  • sp_MSupd_< tablename >, which handles updates.
  • sp_MSdel_< tablename >, which handles deletes.

The <tablename> used in the procedure depends on how the article was added to the publication and whether the subscription database contains a table of the same name with a different owner.

例如,在Programmability catalog下,有三个sp,分别是:dbo.sp_MSdel_dbodt_study,dbo.sp_MSins_dbodt_study,dbo.sp_MSupd_dbodt_study,用以对subscriber端的 dbo.dt_sutdy进行delete,insert和update 操作,这三个sp每次执行时必须保证update,insert或update的数据行数是1,如果更新的记录数量不是1,那么报错。用于Publication的Table必须有PK,PK起到唯一标识一条记录的作用。

1,查看 dbo.sp_MSdel_dbodt_study 的源代码

ALTER procedure [dbo].[sp_MSdel_dbodt_study]
        @pkc1 int
as
begin
    delete [dbo].[dt_study]
    where [id] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end 

delete data command 使用 PK column作为Delete的Filter condition,保证删除一条记录,如果删除的数据行数为0,则报错。

if @@rowcount = 0
  if  @@microsoftversion>0x07320000
    exec sp_MSreplraiserror 20598 

These  commands ensure that if there is no matching record then error 20598 must be raised. "if @@microsoftversion>0x07320000" verifies that you are using a version of SQL Server above SQL 7.

2,示例分析,在Publisher端有如下数据

如果在Publisher端使用如下脚本,删除所有的4个记录

delete dbo.dt_study_publication

那么在Subscriber端,等价的操作是在一个transaction中调用4次dbo.sp_MSdel_dbodt_study

set XACT_ABORT on

begin tran
    exec dbo.sp_MSdel_dbodt_study @pkc1=1
    exec dbo.sp_MSdel_dbodt_study @pkc1=2
    exec dbo.sp_MSdel_dbodt_study @pkc1=3
    exec dbo.sp_MSdel_dbodt_study @pkc1=4
commit
set XACT_ABORT off

如果在Subscriber端,数据有丢失,比如,PKColumn=4 的Record不存在,那么则会导致整个transactino失败,导致数据同步失败。

3,查看dbo.sp_MSins_dbodt_study的源代码

ALTER procedure [dbo].[sp_MSupd_dbodt_study]
        @c1 int = NULL,
        @c2 nvarchar(50) = NULL,
        @c3 bit = NULL,
        @pkc1 int = NULL,
        @bitmap binary(1)
as
begin
if (substring(@bitmap,1,1) & 1 = 1)
begin 

update [dbo].[dt_study] set
        [id] = case substring(@bitmap,1,1) & 1 when 1 then @c1 else [id] end,
        [name] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [name] end,
        [sex] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [sex] end
    where [id] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end
else
begin 

update [dbo].[dt_study] set
        [name] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [name] end,
        [sex] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [sex] end
    where [id] = @pkc1
if @@rowcount = 0
    if @@microsoftversion>0x07320000
        exec sp_MSreplraiserror 20598
end
end 

update data command 使用 PK column作为update的Filter condition,保证更新一条记录,如果更新的数据行数为0,则报错。

4, 查看 [dbo].[sp_MSins_dbodt_study] 的源代码

ALTER procedure [dbo].[sp_MSins_dbodt_study]
    @c1 int,
    @c2 nvarchar(50),
    @c3 bit
as
begin
    insert into [dbo].[dt_study](
        [id],
        [name],
        [sex]
    ) values (
    @c1,
    @c2,
    @c3    )
end  

将表数据插入到表中,在Insert子句中必须显式指定table的所有column name,在Values子句中必须显式为table的所有column赋值。如果插入成功,肯定是插入一条record;如果插入失败,Insert command会报错。

5,更新Subscriber端数据的非主键属性

5.1 查看Publisher和Subscriber data snapshot

Publisher Data Snapshot

subscriber Data Snapshot

5.2 在Publisher 端insert数据

insert into dbo.dt_study
(
ID,
name,
sex
)
values(5,‘abc‘,0)

在Subscriber端查看数据更新

5.3 在Publisher 端更新数据

update dbo.dt_study
set name=‘update5‘
where id=5

在Subscriber端查看数据更新

在Subscriber端update数据

update dbo.dt_study
set name=‘update6‘
where id=5

在Publisher 端更新数据

update dbo.dt_study
set name=‘update7‘
where id=5

在Subscriber端查看数据更新

可以看出,如果在Subscriber端对数据的非主键属性进行更新,那么不影响transaction replication同步数据。

6,更新Subscriber端数据的主键属性

在Subscriber端删除ID=5的记录

delete dbo.dt_study
where id=5

在Publisher 端 删除 dbo.dt_study 中ID>=5的所有记录

delete dbo.dt_study
where id>=5

subscriber Data Snapshot如下,subscriber数据不会更新,数据同步失败。

查看 Replication Monitor,

The row was not found at the Subscriber when applying the replicated command. (Source: MSSQLServer, Error number: 20598)
Get help: http://help/20598

WorkAround:在Subscriber 端中将 缺失的Row PK 补上即可。

insert into dbo.dt_study
(ID,name,sex)
values(5,null,null)

Transaction执行失败,并不会从Distribution database中移除,Distributor Agent 会多次重新执行失败的Transaction。

Transaction 何时从Distribution database中移除?

Transaction commands are stored in the distribution database until they are propagated to all Subscribers or until the maximum distribution retention period has been reached. Subscribers receive transactions in the same order in which they were applied at the Publisher.

时间: 2024-10-08 23:34:15

Transaction Replication1:Subscription PK columns are readonly的相关文章

Transaction Replication2:Transaction

1,Database 的 Trasaction Log File 是用于记录Publication的modification log,在Transaction Replication中,Log Reader Agent 读取Publication的标记为Replcation 的 transaction log,传递到 Distributor 的distribution database中存储起来. Transaction log files are used not only during th

58到家周俊鹏:webpack PK fis,实现前端工程化我更喜欢前者

责编:陈秋歌,关注前端开发领域,寻求报道或者投稿请发邮件chenqg#csdn.net. 欢迎加入"CSDN前端开发者"微信群,参与热点.难点技术交流.请加群主微信「Rachel_qg」,申请入群,务必注明「公司+职位」.另可申请加入CSDN前端开发QQ群:465281214. 2016年,SDCC(中国软件开发者大会)相继走进了上海.深圳.成都.杭州各地.11月18日-20日将在北京完美收官.作为大会的重要分专题,前端开发专题已邀请到58到家高级前端工程师周俊鹏担任大会讲师,现场将分

购物狂欢:谷歌PK亚马逊

腾讯科技讯 10月16日,谷歌(微博)执行董事长埃里克·施密特(Eric Schmidt)日前宣称,谷歌在互联网搜索领域的最大对手就是亚马逊.不管怎么说,这句话可能有一半是真的.在全球搜索领域,谷歌除了微软外没有任何敌手,而寻求各种商品的购物者直接去浏览亚马逊.因此,如果说搜索等同于购物,亚马逊堪称谷歌的对手. 在面对竞争对手时,谷歌不习惯选择逃避.谷歌已经推出自己的购物与快递服务Google Express,每年只需要缴纳95美元会员费,就可以在美国7大城市享受免费送货上门服务.此前,谷歌仅在

最近遇到的若干Web前端问题:disable和readonly,JqueryEasyUI,KindEditor

最近项目中用到了Jquery Easyui和KindEditor等框架组件,问题真不少啊~  一些看起来很简单理所当然的事情,竟然花费了不少时间,才解决好~  1.readonly和disable的区别  readonly:只读,不可编辑,提交表单时,值会提交到后端.  disable:禁止(包含了"只读"和"不可编辑"),提交表单时,值不会提交到后端.      如果需要提交到后端,在表单提交之前,手动把disable修改为false.    text叫只读,se

MySQL系列:innodb源码分析之mini transaction

日志是innodb一个非常重要的模块,在innodb中有两类日志:redo log和undo log.其中redolog日志是用来做数据异常恢复和数据库重启时页数据同步恢复的,redo log是建立在在mini transaction基础上.数据库在执行事务时,通过minitransaction产生redo log来保证事务的持久性. 1.mini transaction三个协议 mini-transcation是用来实现innodb的物理逻辑日志的写入和页恢复的,通过mini-transcat

pip list报错:DEPRECATION: The default format will switch to columns in the future.

一.现象: pip list 显示出以下错误:     DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.二.解决方案:如果你

TimesTen 数据库复制学习:10. 定义classic复制

设计高可用系统 复制的目标为: 1. 提供一个或多个复制数据库,保证数据可以为应用所用 2. 提供复制数据库用于恢复 3. 负载均衡 4. 无中断的软件升级和维护 classic replication scheme支持以下形式: Unidirectional - 这个和ASP有和区别,会切换角色吗 Bidirectional split workload - 双向,属于互备型,两个数据库负责不同的工作负载 Bidirectional distributed workload - 双向,属于双活

事务Transaction 那点事儿

Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要么就不做.也就是说,事务必须是一个不可分割的整体,就像我们在化学课里学到的原子,原子是构成物质的最小单位.于是,人们就归纳出事务的第一个特性:原子性(Atomicity).我靠,一点都不神秘嘛. 特别是在数据库领域,事务是一个非常重要的概念,除了原子性以外,它还有一个极其重要的特性,那就是:一致性(Consistency).也就是

Oracle基础(七):数据库事务

一.基本概念 1.事务(Transaction):是并发控制的基本单位.所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行.所以,应该把它们看成一个事务.事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性. 2.事务与锁 当执行事务操作时,oracle会在被作用的表上家锁,防止其他用户改表的结构. 3.事务的操作过程 1)事务的开始(默认自动开始)