使用更改跟踪实现数据同步

SQL Server 2008 引入了更改跟踪,这是一种轻量型解决方案,它为应用程序提供了一种有效的更改跟踪机制。通常,若要使应用程序能够查询对数据库中的数据所做的更改和访问与这些更改相关的信息,应用程序开发人员必须实现自定义更改跟踪机制。创建这些机制通常涉及多项工作,并且常常涉及使用触发器、timestamp 列和新表组合来存储跟踪信息,同时还会涉及使用自定义清除过程。

通过更改跟踪,可以很容易地编写同步数据的应用,下面是一个使用更改跟踪实现单向数据同步的示例。

1 建立示例环境

-- ====================================================

-- 测试的数据库

USE master;

GO

CREATE DATABASE DB_test;

GO

-- 启用更改跟踪

ALTER DATABASE DB_test SET

CHANGE_TRACKING = ON(

AUTO_CLEANUP = ON, -- 打开自动清理选项

CHANGE_RETENTION = 1 HOURS -- 数据保存期为1

);

ALTER DATABASE DB_test SET

ALLOW_SNAPSHOT_ISOLATION ON; -- 允许在测试数据库中使用 SNAPSHOT 事务隔离级别

GO

-- ====================================================

-- 测试的表

USE DB_test;

GO

-- a. 同步的源表

CREATE TABLE dbo.tb_source(

pk_id int IDENTITY

PRIMARY KEY,

col1 int,

col2 varchar(10),

col3 nvarchar(max),

col4 xml

);

GO

-- 启用更改跟踪

ALTER TABLE dbo.tb_source

ENABLE CHANGE_TRACKING

WITH(

TRACK_COLUMNS_UPDATED = ON -- 记录UPDATE 的列信息

);

GO

-- b. 同步的目录表

CREATE TABLE dbo.tb_Target(

pk_id int

PRIMARY KEY,

col1 int,

col2 varchar(10),

col3 nvarchar(max),

col4 xml

);

GO

-- 记录同步情况的表

CREATE TABLE dbo.tb_Change_Tracking(

id int IDENTITY

PRIMARY KEY,

object_name sysname

UNIQUE,

last_sync_version bigint,

last_update_date datetime

);

GO

2 实现同步处理的存储过程

-- ====================================================

-- 数据同步处理的存储过程

USE DB_test;

GO

-- 数据同步的存储过程- 同步未更新的数据

-- 单次更新,更新完成后退出

CREATE PROC dbo.p_SyncChangeData_tb_Srouce_Target

@last_sync_version bigint = NULL OUTPUT,

@min_valid_version bigint = NULL OUTPUT

AS

SET NOCOUNT ON;

-- ========================================

-- TRY...CATCH 中的标准事务处理模块

-- a. 当前的事务数

DECLARE

@__trancount int;

SELECT

@__trancount = @@TRANCOUNT;

-- TRY...CATCH 处理

BEGIN TRY

-- ========================================

-- 源表信息

DECLARE

@object_name sysname,

@object_id int;

SELECT

@object_name = N'dbo.tb_source',

@object_id = OBJECT_ID(@object_name);

-- ========================================

-- 最后一次同步的版本

IF @last_sync_version IS NULL

BEGIN

SELECT

@last_sync_version = last_sync_version

FROM dbo.tb_Change_Tracking

WHERE object_name = @object_name;

IF @@ROWCOUNT = 0

BEGIN

SET @last_sync_version = CHANGE_TRACKING_MIN_VALID_VERSION(@object_id);

INSERT dbo.tb_Change_Tracking(

object_name, last_sync_version)

VALUES(

@object_name, @last_sync_version);

END;

END;

-- ========================================

-- TRY...CATCH 中的标准事务处理模块

-- b. 开启事务, 或者设置事务保存点

SET TRANSACTION ISOLATION LEVEL SNAPSHOT; -- 使用快照隔离级别的事务

IF @__trancount = 0

BEGIN TRAN;

ELSE

SAVE TRAN __TRAN_SavePoint;

-- ========================================

-- 版本验证

-- a. 验证是否有数据变更(如果上次同步的版本号= 当前数据库的最大版本号,则视为无数据变化)

IF @last_sync_version = CHANGE_TRACKING_CURRENT_VERSION()

GOTO lb_Return;

-- b. 验证同步的版本号是否有效(如果上次同步的版本号< 当前可用的最小版本号,则视为无效)

IF @last_sync_version < CHANGE_TRACKING_MIN_VALID_VERSION(@object_id)

BEGIN

SET @min_valid_version = CHANGE_TRACKING_MIN_VALID_VERSION(@object_id);

GOTO lb_Return;

END;

-- c. 验证同步的版本号是否有效(如果上次同步的版本号> 当前数据库的最大版本号,则视为无效)

IF @last_sync_version > CHANGE_TRACKING_CURRENT_VERSION()

BEGIN

SET @last_sync_version = NULL;

GOTO lb_Return;

END;

-- ========================================

-- 同步数据

-- a. 插入

WITH

CHG AS(

SELECT

DATA.*

FROM dbo.tb_source DATA

INNER JOIN CHANGETABLE(CHANGES dbo.tb_source, @last_sync_version) CHG

ON CHG.pk_id = DATA.pk_id

WHERE CHG.SYS_CHANGE_OPERATION = N'I'

)

INSERT dbo.tb_Target

SELECT * FROM CHG;

-- b. 删除

WITH

CHG AS(

SELECT

CHG.*

FROM CHANGETABLE(CHANGES dbo.tb_source, @last_sync_version) CHG

WHERE CHG.SYS_CHANGE_OPERATION = N'D'

)

DELETE DATA

FROM dbo.tb_Target DATA

INNER JOIN CHG

ON CHG.pk_id = DATA.pk_id;

-- c. 更新

WITH

COL AS(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值