`
yunnick
  • 浏览: 389815 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Oracle存储过程捕获异常没有抛出导致的JDBC异常

阅读更多

      名字起的好拗口。

      这是一个关于执行超时的问题。

      业务场景是这样的:根据要求,需要每天生成若干报表(原始数据量约为4-5GB),使用一个总的存储过程调度几十个子存储过程(由于有依赖关系,存储过程需要串行执行),为了不影响当天的剩下的工作,生成报表有个容忍时间(2-3小时),超过时间后就需要强行终止。

      在测试中发现,使用setQueryTimeout()方法,或者cancel()方法,超时后存储过程确实终止了,并且在记录中可以看到“ORA-01013: 用户请求取消当前的操作”这个异常,但是下面再执行其他的SQL语句(简单的查询),在java端却也爆出了这个错误,导致该SQL执行出错,而且查看日志可以看到,爆出错误的链接(oracle.jdbc.driver.T4CConnection)和执行存储过程的链接是同一个,其他的连接就没问题。

      以上问题不管用最原始的JDBC,c3p0连接池还是用SpringJdbcTemplate,还是更新OJDBC驱动,都无法解决(数据库是Oracle10),最后折腾了半天也没发现是怎么回事。

     存储过程如下,模拟长时间执行:

     

create or replace procedure pro_test is
 err_msg      varchar2(4000);
begin
for i in 1..60
loop
 insert into scott.prolog(id,date, info)values(i, sysdate,'222');
 DBMS_LOCK.sleep(1);
  commit;
end loop;

 exception
  when others then
     err_msg := sqlerrm;
    rollback;
    insert into scott.prolog(id,date, info)values('err', sysdate,err_msg);
    commit;    
    return;

end;

 

      异常在存储过程中捕获,并进行记录,然后直接返回,但这种方式JDBC端察觉不到任何异常。

      最后,尝试在return之前抛出异常,利用下面的语句:

RAISE_APPLICATION_ERROR(-22222, '系统异常'); 
return; 

       然后,超时后JDBC可以捕获到-22222的SQLException,而且再用相同的链接执行任意SQL也不再报错了。

 

      具体什么原因导致了这种情况不得而知,暂且记录一下。盼望有高手解答。

 

1
0
分享到:
评论

相关推荐

    java面试800题

    Q0045 Java中是怎样捕获异常的? "try { //statement01 } catch(Exception e) { //statement02 } finally { //statement03 }" Q0046 一个文件中是否可以有多个public类? 不可以 Q0047 子类是否可以访问父类的...

    疯狂JAVA讲义

    10.2.1 使用try...catch捕获异常 359 10.2.2 异常类的继承体系 360 10.2.3 访问异常信息 363 10.2.4 使用finally回收资源 364 10.2.5 异常处理的嵌套 367 10.3 Checked异常和Runtime异常体系 367 10.3.1 使用...

    java 面试题 总结

    java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法,...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例170 方法中抛出异常 218 实例171 方法上抛出异常 219 实例172 自定义异常类 220 实例173 捕获单个异常 221 实例174 捕获多个异常 222 第8章 枚举与泛型的应用 223 8.1 枚举使用的简介 224 实例175 查看枚举类型...

    超级有影响力霸气的Java面试题大全文档

    java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法...

    JAVA面试题最全集

    如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 finalize?方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的...

    JAVA上百实例源码以及开源项目

    从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始化一个EJB实例 5个目标文件,演示Address ...

    JAVA上百实例源码以及开源项目源代码

    保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始...

Global site tag (gtag.js) - Google Analytics