<强> 背景: 强>
最近遇到一个例子中,客户端程式调用存储过程SP1,过程SP1执行完成后返回结果到客户端。
因为过程SP1执行时间要5秒钟,时间太长端用户无法接受。
分析主过程SP1性能,发现主要是其中调用的子过程SP2执行需要4秒,且子过程SP2中一条SQL因为资料量巨大逻辑复杂已无优化可能。另外子过程SP2的主要是计算审计功能并记录日志作用的。
<强> 设想: 强>
能否让用户执行主过程时不等子过程完成就 子,过程异步方式在后台慢慢的运行吗?
直接通过甲骨文的技术能否实现?
答案是可以的,通过DBMS_JOB。提交下面的方法可以实现。
<强> 实现: 强>
创建日志表:
<前> CREATE TABLE  SFIS1.JOBSUBMIT_LOG ( EXE_TIME 才能,日期, DATAX 才能,,,,,VARCHAR2(5,字节) ) >之前
创建子过程:
<前> REPLACE  CREATE ,或是;PROCEDURE  SFIS1.JOB_SUBMIT (DATA3 ,拷贝,VARCHAR2) 是 开始 ,,,IF DATA3=& # 39; 1 & # 39;然后 ,,,,,,,dbms_lock.sleep(10);,——模拟子过程执行10秒需要 ,,,,,,,insert into sfis1.jobsubmit_log 价值(SYSDATE DATA3); ,,, ,,,,,,,insert into sfis1.jobsubmit_log 价值(SYSDATE DATA3); ,,,最终获得;如果; ,,,提交; 异常 ,,WHEN 别人 ,, ,,,DBMS_OUTPUT.PUT_LINE (& # 39; FAIL2 ! & # 39;),,,,,,,, 结束; >之前
创建主过程:
<前> REPLACE  CREATE ,或是;PROCEDURE  SFIS1.JOB_SP (DATA1 ,拷贝,VARCHAR2, DATA2 ,拷贝,VARCHAR2) 是 ,,START_TIME ,,日期; ,,l_job ,,,,,,,号码; 开始 ,,START_TIME :=, SYSDATE; ,,DBMS_OUTPUT.PUT_LINE (& # 39; Start 时间:& # 39;,| |,TO_CHAR (START_TIME, & # 39; YYYY-MM-DD-HH24: MI: ss # 39;)); ,,DBMS_JOB.submit (l_job, & # 39; SFIS1.JOB_SUBMIT (& # 39; | | data1 | | & # 39;); & # 39;); ,,DBMS_JOB.submit (l_job, & # 39; SFIS1.JOB_SUBMIT (& # 39; | | data2 | | & # 39;); & # 39;); ,才能提交; ,,DBMS_OUTPUT.PUT_LINE (& # 39; Elapsed 时间:& # 39;,| |,CEIL (, (SYSDATE 作用;START_TIME), *, 24, *, 60, *, 60));,,计算主过程运行总时间 异常 ,,WHEN 别人 ,, ,,,,,DBMS_OUTPUT.PUT_LINE (& # 39;失败! & # 39;); 结束; >之前
执行主过程:
<前> exec SFIS1.JOB_SP (& # 39; 1 & # 39; & # 39; 2 & # 39;); >之前结果:
开始时间:2019 - 06 - 04 - 10:11:12
运行时间:0,执行时间0秒,说明子过程已经异步在后台执行了,主过程并没有等待子过程执行完成
查询日志表:
<前> select *,得到sfis1.jobsubmit_log; >之前
2019/6/4 10:11:13 ,,, 2
2019/6/4 10:11:23 ,,,, 1,——进一步说明子过程异步在后台执行
以上,主要通过
并行异步后台执行存储过程。
本文使用技术主要参考汤姆大师:
https://asktom.oracle.com/pls/asktom/asktom.search?tag=execute-procedures-concurently-in-a-procedure ,