Java实时获取oracle变更
http://www.iteye.com/topic/267893
在一个基于数据库的“实时系统”里面,“实时”获取数据库变化是非常重要的,本文主要描述通过Oracle中的捕获进程实时获取数据库变化。
背景:
要做一个车辆GPS监控系统,主要分两块:
1.采集。由GPS厂商提供实时数据,通过UDP包接收
2.展示。前端程序获取到最新GPS数据后,在地图上模拟车辆的运行情况
备选方案:
1.采集程序接收到UDP包并解析后,将数据放入数据库;前端程序轮询数据库以获取最新数据。
2.采集程序接收到UDP包并解析后,将数据放入数据库,同时向前端程序发送一条消息,传递最新数据。
方案评估:
方案1:最简单,最传统;增加不必要的数据库查询,并且非实时,轮询时间间隔不好确定。
方案2:可实现“实时”,但增加采集程序职责,采集程序本不知道前端系统的存在。
最终方案:
最后采取了另一种方案:通过oracle捕获进程捕获数据库变更(采集程序insert或update一条记录时,捕获进程即时获取到该条记录),将变更记录发送到AQ(oracle高级队列,JMS的oracle实现),前端程序只关注AQ,当有新消息到来时,即刻可收到并做相应处理,反映出实时状态。
关于捕获进程,请参考《Streams概述》,《Streams捕获进程》
实现:
SQL代码
创建表空间和用户:
Sql代码
1.Create tablespace streams_tbs datafile 'E:\DBSERVER\ORACLE9I\ORADATA\TESTDB\stream_tbs.dbf' size 25M Reuse autoextend on maxsize unlimited;
2.
3.--修改目标表(要捕获变更的表)追加日志
4.ALTER TABLE myoracle.TEST_GPS_STATUS ADD SUPPLEMENTAL LOG GROUP log_group_gpsstatus_pk (DEVICEID) ALWAYS;
5.
6.
7.create user strmadmin identified by strmadmin default tablespace streams_tbs quota unlimited on streams_tbs;
8.
9.
10.grant connect, resource, select_catalog_role to strmadmin;
授予相应权限
Sql代码
1.grant execute on dbms_aqadm to strmadmin;
2.
3.grant execute on dbms_capture_adm to strmadmin;
4.
5.grant execute on dbms_propagation_adm to strmadmin;
6.
7.grant execute on dbms_streams_adm to strmadmin;
8.
9.grant execute on dbms_apply_adm to strmadmin;
10.
11.grant execute on dbms_flashback to strmadmin;
12.
13.grant execute on dbms_aq to strmadmin;
14.
15.grant execute on dbms_aqjms to strmadmin;
16.
17.grant execute on dbms_aqin to strmadmin;
18.
19.grant execute on dbms_aqjms_internal to strmadmin;
20.
执行系统存储过程分配权限
Sql代码
1.BEGIN
2.DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(
3.privilege => DBMS_RULE_ADM.CREATE_RULE_SET_OBJ,
4.grantee => 'strmadmin',
5.grant_option => FALSE);
6.END;
7./
8.
9.
10.
11.BEGIN
12.DBMS_RULE_ADM.GRANT_SYSTEM_PRIVILEGE(
13.privilege => DBMS_RULE_ADM.CREATE_RULE_OBJ,
14.grantee => 'strmadmin',
15.grant_option => FALSE);
16.END;
17./
18.
以strmadmin帐户登录oracle
创建AQ,类型为JMS消息
Sql代码
1.BEGIN
2. DBMS_AQADM.CREATE_QUEUE_TABLE(
3. Queue_table => 'gpsstatus_queue_table',
4. Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
5. multiple_consumers => false,
6.