数据库:Oracle9i 
功能:将数据库A中的表sysdmlsend 和 sysdmlsendblob 中的数据远程插入到数据库B中的表sysdmlreceive和sysdmlreceiveblob中 
问题:job死 
现象:next date不更新下次执行时间,last date为空,total time刷新时变化 
初步判断:job调用的存储过程执行时,不知什么原因,导致运行不能结束
 
为什么执行insert into这一行时,始终执行不过去,dblink是激活的。有些地方是好的,说明过程本身没有错误,很可能是网络状况不好造成,那为什么不超时抛出呢??附存储过程和job如下: create or replace procedure p_copytablere is 
begin 
insert into sysdmlreceive@dblink select sysid,syssql,0,sdate from sysdmlsend; 
insert into sysdmlreceiveblob@dblink select sysid,startsql,blobcontent,endsql from sysdmlsendblob; 
commit; 
execute immediate 'truncate table sysdmlsend' ; 
execute immediate 'truncate table sysdmlsendblob'; 
commit; 
exception   
  when dup_val_on_index then 
    null;
  when timeout_on_resource then 
    null;
  when invalid_cursor then 
    null;
  when not_logged_on then 
    null;
  when login_denied then 
    null;
  when no_data_found then 
    null;
  when too_many_rows then 
    null;
  when invalid_number then 
    null;
  when zero_divide then 
    null;
  when storage_error then 
    null;
  when program_error then 
    null;
  when value_error then 
    null;
  when cursor_already_open then 
    null;
  when others then   
    null;
end; VARIABLE jobno number; 
begin 
        DBMS_JOB.SUBMIT(:jobno, 'p_copytablere;',  SYSDATE, 'SYSDATE + 30/1440'); 
        commit; 
end; 

解决方案 »

  1.   

    用DBLink不稳定是正常的,我觉得你把往远程DB插入的方式改为远程DB来取会好一点,
      

  2.   

    end 后面另起一行加上/
      

  3.   

    2楼:远程DB来取,也是通过数据库链接啊,一回儿事儿,再说远程DB是上级,管辖了很多下级,只能是下级有新数据了主动向上报。
    3楼:end 后面另起一行加上/ 什么意思?起什么作用?
      

  4.   

    VARIABLE jobno number; 
    begin 
            DBMS_JOB.SUBMIT(:jobno, 'p_copytablere;',  SYSDATE, 'SYSDATE + 30/1440'); 
            commit; 
    end; 这里的间隔时间太短了吧,导致一次还没执行完毕,间隔时间已经到了,说不定积累了好多次了
      

  5.   

    DBLink是一个让人头痛的事件,用Job去调用也是挺危险的,比如你的过程可能没有执行完成,可能Job已经又提交了一个执行过程.另外你也不知道另一端的表是不是锁住了,如果锁住你的过程可能一直处于等待状态.我建议改用另外一种方式去实现就是单独写一个程序(VB,C#,Delphi),一端连本地,一端连远程,连接远程的方式用三层实现,一条一条的插入到远程的数据库,本地加一个LOG表,把有异常的放在LOG表中,另外远程DB可以建立一个临时表,专门用来接收数据,等数据接收完成了,再从临时表搬到正式表,这种方式比较保险,但实现起来也比较复杂一些
      

  6.   

    LZ是在A数据库上对B表进行插入。
    为什么不换成在B数据库上进行对A数据库的查询然后插入呢
    insert into (b数据库) select * from (A数据库)@dblink,
    我们生产系统都是这样实现的。提醒:注意日志跟踪。
      

  7.   

    感谢6楼的详细分析
    我查过有关Job的好多资料,job不会出现你说的那种情况,如果本次没有执行完成,Job不会执行下一次,更不会像5楼说进行累计。
    你说的远端表锁死倒是可能发生的,导致这一端的存储过程执行处于等待状态。但是,这种情况Oracle应该能自行管理啊,不可能远端的表一直被锁死吧。
    单独写一个程序我们也尝试过(失败告终),是用定时器取代了job,但是连接远程还是通过dblink的方式,你说的“连接远程的方式用三层实现”是什么意思?能否给出具体的实现方法。
      

  8.   

    刚刚测试发现:
    出现这种问题后,如果把本地的Oracle服务器重启,再运行JOB,就很快执行完成,数据也同步上去了。能说明什么问题呢?是不是说明跟远端的表死锁没关系?而是本地出了问题?
      

  9.   

    不知道你的具体情况,我总结了几种情况:
    1、网络有问题,可能性小,因为你有抛异常,但是不知道是否在你的时限之内;
    2、你本地查询的表存在排斥锁(DML),因为你是全表查询;
    3、本地表数据太大,同时远程数据库正在执行大量的DML操作,导致回滚段争用。按你的信息,我觉得2的可能性最大