Oracle 发送(异步/同步)请求
编辑
50
2024-05-10
为实时监控Oracle11g数据库数据状态,使用触发器将新数据发送到程序接口进行展示处理。遇到程序接口未启动导致请求超时问题,应考虑使用异步请求以立即响应结果。记录研究成果以警示他人。
先说一下使用到的Oracle技术
UTL_HTTP(用于发送HTTP请求)
dbms_job(用户创建定时任务)
下面是两个核心的储存过程
SendRequests(发送请求,同步请求)
说明:这个储存过程是参考的网络资源,把参数直接通过url方式传入(http://ip/xx?param=xxx),加入异常捕获部分
--发送网络请求
create or replace procedure SendRequests(url in VARCHAR2) is
begin
declare
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(1024); -- URL to post to #这里所有参数的长度根据需求修改
v_url VARCHAR2(4000) := url;
v_param VARCHAR2(4000) := '1';
v_param_length NUMBER := LENGTHB(v_param);
begin
DBMS_OUTPUT.ENABLE (buffer_size=>null);
req := UTL_HTTP.BEGIN_REQUEST(url=> v_url, method => 'POST');
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER(r => req, name => 'Content-Type', value => 'application/x-www-form-urlencoded');
UTL_HTTP.SET_HEADER(req, 'Keep-Alive', 'timeout=1');
UTL_HTTP.SET_HEADER(r => req, name => 'Content-Length', value => v_param_length);
UTL_HTTP.WRITE_RAW (r => req, data => UTL_RAW.CAST_TO_RAW(v_param));
resp := UTL_HTTP.GET_RESPONSE(req);
loop
UTL_HTTP.READ_LINE(resp, value, TRUE); --#这里请求发送完毕后释放内存
DBMS_OUTPUT.PUT_LINE(value);
END LOOP;
UTL_HTTP.END_RESPONSE(resp);
UTL_HTTP.END_REQUEST(req);
EXCEPTION
WHEN OTHERS THEN --#此处捕获了所有异常 并且没有做处理,可以根据自己需求进行个别异常类型处理
null;
end;
end SendRequests;
AsyncSendRequests(发送异步请求)
说明:通过任务调度加SendRequests同步请求实现,参数和同步请求一样 dbms_job 是Oracle内置的任务调度工具,具体使用方式请自行了解,使用这种调用方式可立即执行任务且只执行一次(当任务出错后,重复指定数次自动停止任务,默认好像是16次),这样我们就实现了异步发送请求,无论请求是否成功,都会立即响应
--异步发送网络请求
create or replace procedure AsyncSendRequests(url in VARCHAR2) is
begin
declare
job number;
begin
dbms_job.submit(job, 'SendRequests('''|| url ||''');', sysdate, null);
end;
end AsyncSendRequests;
触发器
触发器应该都会写了,这里只填一个例子
create or replace trigger FindingsOfAudit
after insert or update
on bak_is_flow
for each row
declare
--
begin
--推送数据
--SendRequests('http://nginx.guyubao.com/findings?jyjgbh='||:new.jyjgbh||'&hphm='||:new.hphm||'&lszt='||:new.lszt); --同步请求
AsyncSendRequests('http://nginx.guyubao.com/findings?jyjgbh='||:new.jyjgbh||'&hphm='||:new.hphm||'&lszt='||:new.lszt); --异步请求
end FindingsOfAudit;
总结
无论使用哪种数据库,只要具有相应的API,都可以根据这个示例进行修改。如果支持异步线程,就可以避免使用任务调度。对于Oracle数据库,还可以通过直接调用Java类的方式发送请求。实现思路是使用触发器调用存储过程,存储过程再调用Java类。需要注意的是Oracle内置的JRE版本(例如,Oracle 11g内置JRE版本为1.5)。我并没有对这种方法进行测试,建议大家自行了解。
- 0
- 0
-
赞助
支付宝微信 -
分享