网断了,job停了

来源:互联网 发布:php接入微信公众平台 编辑:程序博客网 时间:2024/04/28 10:45

job(文中用j1代之)执行存储过程(p1)。p1中通过dblink对远程表做查询。另外P1中对others异常做了处理,把所有异常记录到日志中。

由于厂里停电,导致到远程数据库服务器的通信中断。j1在当前也停止了工作。查看j1,broken 为 Y,失败16次。

这就奇怪了,既然做了异常处理,p1中的所有异常(包括网络异常)都会被捕获,并记录到日志,j1根本就不会意识到p1执行失败,那怎么会出现失败16次导致j1 broken的呢?

查询日志发现,在j1上次执行时间内,根本没有该存储过程的任何错误日志。也就是说,j1失败16次但p1可能根本没执行。

查看了一下j1失败那段时间的alter日志有所发现:

Tue Apr 26 17:47:10 2011
Errors in file d:/oracle/product/10.2.0/admin/l25steel/bdump/l25steel_j000_4120.trc:
ORA-12012: 自动执行作业 269 出错
ORA-04045: 在重新编译/重新验证 COMMUNICATION.DATAFROML3 时出错
ORA-04052: 在查找远程对象
SM.PP_SM_IRON_SAMPLE_T@DBLINK_L3IRON_L25 时出错
ORA-00604: 递归 SQL 级别 4 出现错误
ORA-12170: TNS: 连接超时

原来p1是被重新编译了,由于网络中断导致抄不到远程对象,因而编译失败。这要就解释了为什么p1没被执行而j1失败了16次。

 

又是网络惹的祸。但怎么才能让程序包容网络错误呢?oracle非要重新编译存储过程,也不知道它什么时候才重新编译。

办法就是使用动态sql语句,骗过oracle,不让它帮你编译。

例如原来的存储过程p1,新建一个过程p2:

begin

strsql:='p1';
execute strsql;
exception when others
****

end

这样p1就作为动态语句在p2中执行。即使p1无效了(被删了,或者编译失败),p2仍然有效,能被执行。

不过要提醒一点的是,这样可能把原本能在静态编译时发现的错误引入到运行时。

开发人员和管理员必须好好读日志了。

原创粉丝点击