最后,请注意在这个例子中,Order表中行在路由OrderLineItem表中相关联的行时必须存在,因为当路由发生的时候,select语句正在运行,select语句的运行不是在数据变化第一次被捕获的时候运行的。
3.6.5. Scripted Router
当你需要更灵活的选择要路由的节点的逻辑时,scripted router可能会用到。目前可用的脚本语言是Bean Shell。BeanShell是一种类Java的脚本语言。Bean Shell脚本语言的文档可以在http://www.beanshell.org中查看。
Bean Shell类型的Router的router_type是”bsh“。Route_expression是一个有效的BeanShell 脚本:
1. 增加一个节点的ID到目标节点的集合中
2. 返回一个包含多个节点ID的新的集合
3. 返回一个节点的ID
4. 如果目标组中所有的节点都要被路由就返回true,相反返回false。
脚本返回的是节点的列表。这些节点都是合法的org.jumpmind.symmetric.model.Node对象。数据列当前值和旧值可以再脚本中使用,使用一个Java对象代表一个列的数据。列明需要使用大写。旧的值的引用需要使用”OLD_“前缀。
如果你需要访问SymmetricDS服务,可以使用engine变量访问一个org.jumpmind.symmetric.ISymmetricEngine接口的实例。
在下面的例子中,node_id是STORE_ID和WORKSTATION_NUMBER的组合,这两个都是要被路由的表中的列:
insert into SYM_ROUTER (router_id,
source_node_group_id,target_node_group_id, router_type,
router_expression,create_time, last_update_time) values
('corp-2-store-bsh','corp','store', 'bsh', 'targetNodes.add(STORE_ID +
"-" +WORKSTATION_NUMBER);', current_timestamp, current_timestamp);
同样的功能可以简单地返回Node ID来完成。Bah脚本的最后一行总司返回这个值。
insert into SYM_ROUTER (router_id,
source_node_group_id,target_node_group_id, router_type,
router_expression,create_time, last_update_time) values
('corp-2-store-bsh','corp','store', 'bsh', 'STORE_ID + "-" +
WORKSTATION_NUMBER',current_timestamp, current_timestamp);
下面的例子中,如果FLAG列被改变的化,数据会被同步到所有的节点,FLAG没有被改变的话,将不会同步到任何节点。注意,这里我们使用”OLD_“前缀,来访问列的旧值。
insert into SYM_ROUTER (router_id,
source_node_group_id,target_node_group_id, router_type,
router_expression,create_time, last_update_time) values
('corp-2-store-flag-changed','corp','store', 'bsh', 'FLAG != null
&&!FLAG.equals(OLD_FLAG)', current_timestamp,
current_timestamp);
下面的例子中,这个脚本遍历每一个合法的节点,检查是否名为STATION的列去掉两端的空格后是否等于external_id的值。
insert into SYM_ROUTER (router_id,
source_node_group_id,target_node_group_id, router_type,
router_expression,create_time, last_update_time) values
('corp-2-store-trimmed-station','corp','store', 'bsh', 'for
(org.jumpmind.symmetric.model.Nodenode : nodes) { if (STATION != null
&&node.getExternalId().equals(STATION.trim())) {
targetNodes.add(node.getNodeId());} }', current_timestamp,
current_timestamp);
3.6.6. Audit Table Router
Audit Router通过记录一个router创建和更新的审计表中数据变化捕获数据变化(只要auto.config.database被设置为true)。Router创建一个表,表的名字是要捕获的数据的表名加上”_AUDIT“后缀。这个表将拥有与原始表相同的结构,还有3个附加的列。
表中增加了三个额外的审计列:
1. AUDIT_ID:表的主键
2. AUDIT_TIME:数据变化发生的时间
3. AUDIT_EVENT:发生在这行数据的DML类型
下面是创建一个audit router的例子:
insert into SYM_ROUTER (router_id,
source_node_group_id,target_node_group_id, router_type, create_time,
last_update_time)values ('audit_at_corp','corp', 'local', 'audit',
current_timestamp,current_timestamp);
Audit Router为一个组连接捕获数据。为了使上面的AuditRoute能够工作,它必须使用”R“action类型,联系到一个node_group_link上。”R“代表”Only Route To“。在上面的例子中,我们关联到一个local 组。这里,local组是为audit router新创建的。没有节点数据local节点组。如果corp节点上,一个联系到audit Router触发,一个新的audit表将会在corp节点创建,新变化的数据也会被插入到audit表中。