1.TI数据同步原理
TI是利用对源数据库中相应表的数据的增、删、改进行监控来实现数据同步的,这主要通过表的“触发器”来实现数据监控的。
TI数据同步的原理如下:
2.使用前的预备
在安装东方通数据交换产品TI&TLQ 之前,需要做如下的准备工作:
2.1安装JDK
缺省安装JDK 1.3 或 1.4 ,然后配置path、classpath、java_home。例如:
java_home=c:/jdk130 (安装路径)
classpath=.;C:/jdk13/lib/tools.jar;C:/jdk13/lib/dt.jar;C:/jdk13/bin;
path= C:/jdk13/bin;
2.2JDBC驱动程序
根据需要同步的实际数据库的版本,准备相应的JDBC驱动程序。为了方便配置TI,最好现把JDBC的驱动程序包设置到系统的环境变量classpath中。
MS SQLServer 的JDBC:msbase.jar、mssqlserver.jar、mssqlserver4v65.jar、msutil.jar;
Sybase的JDBC:sybase.jar;
Oracle的JDBC:class12.jar;
注意:各个数据库的不同版本的JDBC的驱动程序有差异,所以JDBC的版本与数据库的版本一定要匹配!
3.安装配置TLQ
3.1安装TLQ
缺省安装TLQ至结束,也可以根据操作人员的配置进行安装。系统提供了WIN 和IBM AIX 两种操作平台的安装。
注意:1)安装完成之后,要把安装文件中的 TlqLicense 文件拷贝至 ../TongTech/TLQ6.2/Etc 中。2)TLQ必须与TI安装在同一台计算机上面。
3.2配置TLQ
注意:在所有的配置过程中都区分大小写(因为TLQ底层是C实现的)。
3.2.1本地节点
本地配置->静态配置—>核心配置—>本地节点。
本地节点最好取一个与实际业务相关的名称。别名最好取的与节点名一致,便于记忆。
3.2.2对方节点
本地配置->静态配置—>核心配置—>上级节点、下级节点
对方节点分为“上级节点”和“下级节点”。一般,如果“本地节点”是源数据端,则配“上级节点”,否则配“下级节点”。
在配“上级节点”时,需要对方节点的“节点名”、“IP地址”以及“端口号”,所有节点的“端口号”缺省为“ 10240 ” 。
3.2.3消息队列
本地配置->静态配置—>核心配置—>发送队列、接收队列
消息队列分为“发送队列”和“接收队列”。如果“本地节点”是源数据端则配置“发送队列”,如果“本地节点”是目的数据端则配置“接收队列”。
配置“发送队列”时,最好取一个有含义的队列名称,并选择“目的节点”(在“对方节点”中已经配置),输入“目的节点”的“接收队列名”。注意:“接收队列名”一定要与“目的节点”的完全一致。
配置“接收队列”时,只要输入一个有含义的名称即可。
3.2.4节点配置
系统->节点配置。
在“系统”菜单中的“节点配置”中添加“本地节点”或远程的其他节点,便可以实现相关节点的“远程配置”和“节点监控”功能。
远程节点的“远程配置”功能与本地节点的各项配置操作类同。
注意:在节点配置中的“监控端口号”缺省为“10242”,即节点端口号加“2”。
3.2.5节点监控
监控->节点监控
利用“节点监控”功能,可以实现所有节点的监控,并验证上下级节点是否正常连通。
4.安装配置TI
4.1安装TI
缺省安装即可。
4.2配置TI
菜单路径:工具->选项->JAVA
Command:启动Java虚拟机的路径(是JDK包下的java.exe所在路径)
Working Directory:属性文件所在路径。
ClassPath:TI将自动获取系统的ClassPath值。除此之外,(1)如果ClassPath没包含数据库的JDBC驱动程序JAR包,则需要添加。(2)增加TLQ的API接口JAR包,该包被安装在 ../TongTech/TLQ6.2/java/lib/ tlqadapter.jar。
其他:缺省即可。
4.3属性文件
TI的各个适配器的配置结果被存放在一个*.props 属性文件中。配置人员可以在图形化的TI AF编辑器中完成源组件与目的组件的配置,也可以在*.props 属性文件中直接进行编辑,然后在TI AF编辑器中打开运行。
5.实现数据同步
5.1配置源数据库
根据“1. 数据同步原理”的描述,需要在源数据库中进行如下几个方面的设置。
5.1.1生成存储过程和表
在安装TI的目录 ../TongIntegrator/samples/sql/.. 中,有不同常用关系型数据库的SQL脚本文件。配置人员只需要根据实际的数据库产品选择相应的SQL文件执行,即可在源数据库中创建TI需要的存储过程和表。不同的数据库可能创建的对象不同,但一下内容是一致的,也是我们需要了解的:
存储过程:
BCG_QueueMsg:该存储过程用于负责把数据变化情况记录到系统表BCG_Msg中。
表:
BCG_Msg:存放源表数据变化的记录。该表的数据是由各个源表的触发器通过调用存储过程BCG_QueueMsg生成的。TI直接监控该表的数据,并根据表中数据确定要传输的具体数据,实现数据同步。TI同步完成之后,将删除BCG_QueueMsg中的相应数据。BCG_Msg中存放了ServiceID、TypeID、操作类型(insert、update、delete)以及10个以内的源表的主键。通过主键,TI才能定位具体的数据记录,所以非常重要,主键的确定在表的触发器中要手工完成,一定要注意。
BCG_MsgService:需要手工配置的数据。ServiceID是生成BCG_Msg中数据的基础数据。
BCG_MsgType:需要手工配置的数据。TypeID是生成BCG_Msg中数据的基础数据。
5.1.2初始化Service和Type表
BCG_MsgService:配置人员根据业务特点自己划分,一般一类同步的数据建一个即可。例如:(1,“PDM-CQMIS”),其中的ID为手工设置。
BCG_MsgType:配置人员手工设置,一般和要同步的表名一致,这样便于记忆。例如,如果有一个需要同步的表名为bas_stock_route,则在BCG_MsgType中可设置一个类型为(1,“bas_stock_route”),其中的ID为手工设置。
5.1.3建源表触发器
5.1.3.1Insert触发器
CREATE TRIGGER bas_stock_route_insert ON dbo.bas_stock_route
FOR insert AS
BEGIN
--定义变量,主要在游标中使用
declare @item_id varchar(30),@factory_name varchar(30)
--在inserted表中检索所有的要新增的数据的主键(或能唯一标识记录的字段组合)
declare cursor_insert cursor for select item_id,factory_name from inserted
open cursor_insert
fetch cursor_insert into @item_id,@factory_name
while @@fetch_status=0
begin
--调用存储过程BCG_QueueMsg,@MsgTypeName、@MsgServiceName为BCG_MsgType和BCG_MsgService中设置的值,实际上@MsgTypeName为当前表名;操作类型为“insert”;@MsgParamn为当前表的主键,即游标中检索的字段组合。注意:@MsgParamn都是字符型,如果不是字符型则需要转换成字符型。
exec BCG_QueueMsg @MsgTypeName = 'bas_stock_route', @MsgServiceName ='pdm' , @OperationType ='insert' , @MsgParam1 = @item_id,@MsgParam2 = @factory_name
fetch cursor_insert into @item_id,@factory_name
end
close cursor_insert
deallocate cursor_insert
END
5.1.3.2Update触发器
就目前的TI的版本来看,对update触发器分为两种情况:
(1)表的主键不会改变的情况
这种情况主要是指表中数据的主键值一旦生成就不会改变的情况,例如用“序列号”做主键的情况。这种情况与“ insert触发器”一样:
CREATE TRIGGER tbupdate ON dbo.TN_QFCQ_物料编码
FOR update AS
BEGIN
--定义变量,主要在游标中使用
declare @tid1 int
--在inserted表中检索所有的要新增的数据的主键(或能唯一标识记录的字段组合)
declare cursor_insert cursor for select cn_id from inserted
open cursor_insert
fetch cursor_insert into @tid1
while @@fetch_status=0
begin
--调用存储过程BCG_QueueMsg,@MsgTypeName、@MsgServiceName为BCG_MsgType和BCG_MsgService中设置的值,实际上@MsgTypeName为当前表名;操作类型为“update”;@MsgParamn为当前表的主键,即游标中检索的字段组合。注意:@MsgParamn都是字符型,如果不是字符型则需要转换成字符型。
exec BCG_QueueMsg @MsgTypeName = 'tn_qfcq_物料编码', @MsgServiceName ='pdm' , @OperationType ='update' , @MsgParam1 = convergt(varchar(30),@stid)
fetch cursor_insert into @tid1
end
close cursor_insert
deallocate cursor_insert
END
(1)表的主键可能会改变的情况
这种情况主要是指表中数据的主键值也可能会被更改的情况,例如用“物料编码”做主键的情况。针对这种情况,我们采用“先删除、后新增”的处理方式。
CREATE TRIGGER bas_stock_route_update ON dbo.bas_stock_route
FOR update AS
BEGIN
--定义变量,主要在游标中使用
declare @item_id varchar(30),@factory_name varchar(30)
--在deleted表中检索所有的要新增的数据的主键(或能唯一标识记录的字段组合)
declare cursor_delete cursor for select item_id,factory_name from deleted
open cursor_delete
fetch cursor_delete into @item_id,@factory_name
while @@fetch_status=0
begin
--调用存储过程BCG_QueueMsg,@MsgTypeName、@MsgServiceName为BCG_MsgType和BCG_MsgService中设置的值,实际上@MsgTypeName为当前表名; 操作类型为“delete”;@MsgParamn为当前表的主键,即游标中检索的字段组合。注意:@MsgParamn都是字符型,如果不是字符型则需要转换成字符型。
exec BCG_QueueMsg @MsgTypeName = 'bas_stock_route', @MsgServiceName ='pdm' , @OperationType ='delete' , @MsgParam1 = @item_id,@MsgParam2 = @factory_name
fetch cursor_delete into @item_id,@factory_name
end
close cursor_delete
deallocate cursor_delete
--在inserted表中检索所有的要新增的数据的主键(或能唯一标识记录的字段组合)
declare cursor_insert cursor for select item_id,factory_name from inserted
open cursor_insert
fetch cursor_insert into @item_id,@factory_name
while @@fetch_status=0
begin
--调用存储过程BCG_QueueMsg,@MsgTypeName、@MsgServiceName为BCG_MsgType和BCG_MsgService中设置的值,实际上@MsgTypeName为当前表名;操作类型为“insert”;@MsgParamn为当前表的主键,即游标中检索的字段组合。注意:@MsgParamn都是字符型,如果不是字符型则需要转换成字符型。
exec BCG_QueueMsg @MsgTypeName = 'bas_stock_route', @MsgServiceName ='pdm' , @OperationType ='insert' , @MsgParam1 = @item_id,@MsgParam2 = @factory_name
fetch cursor_insert into @item_id,@factory_name
end
close cursor_insert
deallocate cursor_insert
END
5.1.3.3Delete触发器
CREATE TRIGGER bas_stock_route_delete ON dbo.bas_stock_route
FOR delete AS
BEGIN
--定义变量,主要在游标中使用
declare @item_id varchar(30),@factory_name varchar(30)
--在deleted表中检索所有的要新增的数据的主键(或能唯一标识记录的字段组合)
declare cursor_delete cursor for select item_id,factory_name from deleted
open cursor_delete
fetch cursor_delete into @item_id,@factory_name
while @@fetch_status=0
begin
--调用存储过程BCG_QueueMsg,@MsgTypeName、@MsgServiceName为BCG_MsgType和BCG_MsgService中设置的值,实际上@MsgTypeName为当前表名; 操作类型为“delete”;@MsgParamn为当前表的主键,即游标中检索的字段组合。注意:@MsgParamn都是字符型,如果不是字符型则需要转换成字符型。
exec BCG_QueueMsg @MsgTypeName = 'bas_stock_route', @MsgServiceName ='pdm' , @OperationType ='delete' , @MsgParam1 = @item_id,@MsgParam2 = @factory_name
fetch cursor_delete into @item_id,@factory_name
end
close cursor_delete
deallocate cursor_delete
END
5.2设置TI
5.2.1设置源组件
5.2.1.1关系型数据库
如果源组件是关系型数据库,则采用源组件JdbcSqlSource。必须配置的属性如下:
Name | (随便填写) |
DatabaseType | 选择源数据库类型 |
JdbcDriver | 源数据库的JdbcDriver的驱动程序。常用的JdbcDriver如下: SQLServer:com.microsoft.jdbc.sqlserver.SQLServerDriver Sybase:com.sybase.jdbc.SybDriver Oracle:oracle.jdbc.driver.OracleDriver DB2:COM.ibm.db2.jdbc.net.DB2Driver |
JdbcUrl | 源数据库的Jdbc访问字符串。常用的如下: SQLServer:jdbc:microsoft:sqlserver://193.9.200.115:1433; SelectMethod=cursor;databasename=wh Sybase:jdbc:sybase:Tds:193.9.200.154:4100 Oracle:jdbc:oracle:thin:@193.9.200.15:1521:ora9i DB2:jdbc:db2://193.9.200.15:6789/test |
MsgServiceName | 服务名。与表BCG_MsgService中的对应一致。 |
PassWord | 数据库密码 |
UserName | 数据库登录名 |
DataBase | 数据库名。注意:只有在Sybase数据库时才需要。 |
Type++ | 用于添加Type。与表BCG_MsgType中的对应一致。当输入一个新的Type时,系统将激动增加一个Typen。Type 实际上是在源数据库中定位了一张数据表(Table)。 |
Typen.SQLStatement | 填写检索数据的SQL语句:Select ID,name from custom Where ID=|MsgParam1| and name = ‘| MsgParam2|’。。。,注意:1)select出的字段是要同步的内容,不需要同步的不用select出来;2)where子句中条件个数要与BCG_Msg中该类型Type(实际就是表Table)的MsgParam的个数一致,并且要与实际的表Table的字段对应,注意MsgParam的大小写;3)MsgParam要用竖线||括起来,并且如果是MsgParam描述的字段是字符串类型,则必须用引号‘||’括起来。 |
5.2.1.2TLQ
如果源组件是TLQ,则采用源组件Tlq62Source。必须配置的属性如下:
Name | (随便填写) |
RcvQueueName | 本地节点TLQ的接收队列的名称 |
5.2.2设置目的组件
5.2.2.1关系型数据库
如果目的组件是关系型数据库,则采用目的组件SQLSink。必须配置的属性如下:
Name | (随便填写) |
JdbcDriver | 源数据库的JdbcDriver的驱动程序。常用的JdbcDriver如下: SQLServer:com.microsoft.jdbc.sqlserver.SQLServerDriver Sybase:com.sybase.jdbc.SybDriver Oracle:oracle.jdbc.driver.OracleDriver DB2:COM.ibm.db2.jdbc.net.DB2Driver |
JdbcUrl | 源数据库的Jdbc访问字符串。常用的如下: SQLServer:jdbc:microsoft:sqlserver://193.9.200.115:1433; SelectMethod=cursor;databasename=wh Sybase:jdbc:sybase:Tds:193.9.200.154:4100 Oracle:jdbc:oracle:thin:@193.9.200.15:1521:ora9i DB2:jdbc:db2://193.9.200.15:6789/test |
PassWord | 数据库密码 |
UserName | 数据库登录名 |
Charset | 字符集。注意:Sybase数据库时,字符集设置为“cp936”。 |
DataBase | 数据库名。注意:只有在Sybase数据库时才需要。 |
Type++ | 用于添加Type。注意:1)一定要与源组件中的Type对应一致,而不是目的数据表的名称;2)此处与配置源组件不同,对于源组件每个Type,此处要设置成三个:TypeNameinsert、TypeNameupdate、TypeNamedelete。 |
TypeNameinsert.SQLStatement1 | 填写插入数据的SQL语句:insert into SinkTableName(SinkFieldName1,SinkFieldName2,…) values(%SourceFieldName1%,’ % SourceFieldName2%’…..)。注意:1)SinkTableName为目的数据库中目的表的名字,SinkFieldName1为目的表的字段名;2)SourceFieldName1为源组件中相应Type的SQL语句中的Select子句中的字段名称;3)SourceFieldName1要用百分号%%括起来,并且必须全是大写,并且如果是描述的字段是字符串类型,则必须用引号‘%%’括起来。 |
TypeNameupdate.SQLStatement1 | 填写修改数据的SQL语句:update SinkTableName set SinkFieldName1 = %SourceFieldName1% ;SinkFieldName2 =’ % SourceFieldName2%’…..where SinkPKName1 = % SourceFieldName1% and SinkPKName1 = ‘% SourceFieldName2%’ and … 。注意:1)SinkTableName为目的数据库中目的表的名字,SinkFieldName1为目的表的字段名;2)SourceFieldName1为源组件中相应Type的SQL语句中的Select子句中的字段名称;4)SourceFieldName1要用百分号%%括起来,并且必须全是大写,并且如果是描述的字段是字符串类型,则必须用引号‘%%’括起来。 |
TypeNamedelete.SQLStatement1 | 填写删除数据的SQL语句:delete from SinkTableName where SinkPKName1 = %MsgParam1% and SinkPKName1 = ‘%MsgParam1%’ and ….。注意:1)SinkTableName为目的数据库中目的表的名字; 2) MsgParam1与源Type在表BCG_MsgType中的内容对应一致,是描述主键的;3)MsgParam1要用百分号%%括起来,并且必须全是大写,并且如果是描述的字段是字符串类型,则必须用引号‘%%’括起来。 |
5.2.2.2TLQ
如果目的组件是TLQ,则采用目的组件Tlq62Sink。必须配置的属性如下:
Name | (随便填写) |
TlqRouteExpiry.Default | 设置为 -1。 |
TlqRouteRcvQueueName.Default | 本地节点TLQ的发送队列的名称 |