Oracle中的定时使命

打印 上一主题 下一主题

主题 808|帖子 808|积分 2424

目录

一、了解什么是定时使命?
二、创建job
三、检察job
四、删除Job
五、制止Job
六、立即执行job
七、修改job
八、job执行失败 
九、job用法


一、了解什么是定时使命?

job是oracle的定时使命,又叫定时器,定时作业,作业定时地自动执行一些脚本,或作数据备份,或作数据提炼,或作数据库性能的优化,或作重建索引等等的工作,必要用到job。
Job是一种被调度执行的使命。Job可以是一个PL/SQL块、一个SQL语句、一个外部脚本或程序等。它们可以被定时调度执行,也可以被手动启动执行。
二、创建job

Ⅰ、语法一
  1. declare
  2. v_job_id number;
  3. begin
  4.   dbms_job.submit(job      =>v_job_id,           --job号
  5.                   what     =>'pro_name/DML;',    --定时执行的脚本(简称你要干什么)
  6.                   next_date=>sysdate+1,          --第一次执行的时间
  7.                   interval =>'SYSDATE+1/24/60'   --间隔时间
  8.                   );
  9.   --commit;
  10. end;
复制代码
该语法是利用dbms_job包提交一个定时使命:


  • 1. `declare`和`begin`是PL/SQL代码块的开始和竣事标志。
  • 2. `v_job_id`是一个变量,用于存储job的id号。
  • 3. `dbms_job.submit`是提交一个job的过程,包括以下参数:
  •    - `job`:job的id号,由Oracle自动天生。
  •    - `what`:定时执行的脚本,可以是一个存储过程或SQL语句。
  •    - `next_date`:job第一次执行的时间,可以是一个日期类型的变量或者表达式。
  •    - `interval`:job的执行间隔时间,可以是一个日期类型的变量或者表达式,例如`SYSDATE+1/24/60`表示每隔1分钟执行一次。
  • 4. `commit`是一个事务提交语句,用于将提交的job保存到数据库中。
   注意:
  利用dbms_job提交的job只能在Oracle数据库中执行,不能跨数据库执行。另外,利用dbms_job提交的job在Oracle 10g及以上版本中已经被废弃,推荐利用dbms_scheduler包提交job。
   比如创建定时使命,每分钟执行一次pkg_2.p1,向emp2表中插入员工编号为7788的员工信息:
  1. declare
  2. v1 number;
  3. begin
  4.   dbms_job.submit(job => v1,
  5.                   what => 'insert into emp2 select * from emp where empno=7788;',
  6.                   next_date => sysdate,--立即执行
  7.                   interval => 'SYSDATE+1/24/60');
  8.   commit;
  9. end;
复制代码
其中emp2表为空表,查询当前时间,然后我们执行这个定时使命
  1. select sysdate from dual;
复制代码

 等待一段时间后,我们检察表emp2内的数据:

经过四分钟后,从表中可以发现有四条数据。
Ⅱ、语法二:
利用DBMS_SCHEDULER包来创建和管理job,详细语法如下:
  1. BEGIN
  2.   DBMS_SCHEDULER.CREATE_JOB (
  3.     job_name        => 'job_name',           -- job的名称
  4.     job_type        => 'PLSQL_BLOCK',        -- job的类型,可以是PLSQL_BLOCK、STORED_PROCEDURE等
  5.     job_action      => 'begin my_proc(); end;',  -- job执行的脚本或存储过程
  6.     start_date      => SYSTIMESTAMP,         -- job开始执行的时间
  7.     repeat_interval => 'FREQ=DAILY; INTERVAL=1',  -- job执行的间隔时间
  8.     enabled         => TRUE                  -- 是否启用job
  9.   );
  10. END;
  11. /
复制代码
DBMS_SCHEDULER包提供了丰富的job管理功能,可以设置job的执行时间、执行间隔、执行次数、执行优先级、并发控制等属性,实际应用中可以根据详细需求灵活配置。 
三、检察job

  1. select * from user_jobs;
复制代码
结果如下:

从运行结果中可以知道定时使命的JOB编号为23,登任命户为SCOTT等信息。
其中user_jobs是一个视图,是 Oracle 数据库中的一个体系表,它用于存储由 DBMS_JOB.SUBMIT 提交的作业(job)的信息。该表包含了提交的作业的 ID 号、作业的描述、作业的下一次执行时间、作业的执行间隔时间、作业的状态等信息。用户可以查询该表来获取作业的信息,也可以利用该表来管理作业的状态、修改作业的执行时间等。
   注意:
  该表只能检察和管理由当前用户提交的作业,不能检察和管理其他用户提交的作业。
  着实在Oracle中,可以利用以下SQL语句来检察定时使命Job的信息:
  1. SELECT job_name, job_type, enabled, state, last_start_date, next_run_date
  2. FROM dba_scheduler_jobs;
复制代码
该语句会列出所有的Job,包括Job的名称、类型、是否启用、状态、前次执行时间和下次执行时间等信息。其中,dba_scheduler_jobs是一个体系视图,可以检察所有的Job信息。如果只必要检察当前用户的Job,可以利用USER_SCHEDULER_JOBS视图
另外,也可以利用以下SQL语句来检察某个Job的详细信息:
  1. SELECT *
  2. FROM dba_scheduler_jobs
  3. WHERE job_name = 'job_name';
复制代码
该语句会列出指定Job的所有信息,包括Job的类型、执行时间、重复间隔、执行程序等。
   检察定时使命Job的信息只必要利用一些体系视图或者SQL语句就可以轻松实现。这些信息可以帮助管理员了解定时使命的执行情况,实时发现息争决问题。
  四、删除Job

Ⅰ、调用dbms_job.remove实现:
  1. call dbms_job.remove(23);
  2. commit;
复制代码
从上面检察job信息知道编号是23!然后调用存过 dbms_job.remove
 其中dbms_job.remove是一个包名,是Oracle 数据库中的一个过程,用于删除一个已经存在的作业(job)。它的语法如下:
  1. DBMS_JOB.REMOVE (
  2.    job IN BINARY_INTEGER);
复制代码
其中,job 参数表示要删除的作业的 ID 号。调用该过程后,指定 ID 号的作业将被从数据库中删除。
   注意:
  该过程只能删除由 DBMS_JOB.SUBMIT 提交的作业,不能删除由 DBMS_SCHEDULER.SUBMIT 创建的作业。
  Ⅱ、利用下面语句完成job删除:
  1. BEGIN
  2.   DBMS_SCHEDULER.DROP_JOB (
  3.     job_name        => 'job_name',           -- job的名称
  4.     force           => FALSE                 -- 是否强制删除job
  5.   );
  6. END;
  7. /
复制代码
其中,job_name是要删除的Job的名称,force参数表示是否强制删除Job。如果force参数为TRUE,则会强制删除Job及其关联的所有对象(例如,程序、链、计划等)。如果force参数为FALSE,则只会删除Job本身。
五、制止Job

  1. begin
  2.   dbms_job.broken(23,true);
  3.   commit;
  4. end;
复制代码
 上述命令即可制止job的执行。
其中dbms_job.broken 是 Oracle 数据库中的一个过程,用于标记一个作业(job)为失效状态。它的语法如下:
  1. DBMS_JOB.BROKEN (
  2.    job IN BINARY_INTEGER,
  3.    broken IN BOOLEAN,
  4.    next_date IN DATE DEFAULT NULL,
  5.    interval IN VARCHAR2 DEFAULT NULL);
复制代码
其中,job 参数表示要标记为失效的作业的 ID 号;broken 参数表示是否将作业标记为失效状态,true 表示失效,false 表示恢复;next_date 参数表示作业下一次执行的时间;interval 参数表示作业执行的间隔时间。
调用该过程后,指定 ID 号的作业将被标记为失效状态。如果 broken 参数为 true,则该作业将被标记为失效,不再执行;如果为 false,则该作业将被恢复为正常状态。如果指定了 next_date 和 interval 参数,则会更新作业的下一次执行时间和执行间隔时间。
或者利用下面命令也可以实现制止job:
  1. BEGIN
  2.   DBMS_SCHEDULER.STOP_JOB (
  3.     job_name        => 'job_name',
  4.     force_option    => 'IMMEDIATE',
  5.     commit_semantics=> 'ABORT');
  6. END;
复制代码
其中,job_name是要制止的Job的名称,force_option参数表示制止Job的方式,可以为IMMEDIATE或CASCADE。如果force_option为IMMEDIATE,则会立即制止Job的执行。如果force_option为CASCADE,则会将Job及其关联的所有对象都制止。commit_semantics参数表示制止Job的提交语义,可以为COMMIT或ABORT。如果commit_semantics为COMMIT,则会提交Job的事务,并将Job状态设置为STOPPED。如果commit_semantics为ABORT,则会回滚Job的事务,并将Job状态设置为BROKEN。
六、立即执行job

  1. call dbms_job.run(23);
复制代码
dbms_job.run 是 Oracle 数据库中的一个过程,用于立即执行一个作业(job)。它的语法如下:
  1. DBMS_JOB.RUN (
  2.    job IN BINARY_INTEGER);
复制代码
其中,job 参数表示要执行的作业的 ID 号。调用该过程后,指定 ID 号的作业将被立即执行一次。如果该作业正在执行中,则该过程不会产生任何结果,直到该作业执行完毕后再执行一次。
    注意:
  该过程也是只能执行由 DBMS_JOB.SUBMIT 提交的作业,不能执行由 DBMS_SCHEDULER.SUBMIT 创建的作业。
  七、修改job

  1. BEGIN
  2.   DBMS_SCHEDULER.SET_ATTRIBUTE (
  3.     name           => 'job_name',            -- job的名称
  4.     attribute      => 'start_date',         -- 要修改的属性名称
  5.     value          => SYSTIMESTAMP + INTERVAL '1' DAY  -- 修改后的属性值
  6.   );
  7. END;
  8. /
复制代码
 该语法是利用DBMS_SCHEDULER包修改job的开始时间:


  • 1. `BEGIN`和`END`是PL/SQL代码块的开始和竣事标志。
  • 2. `DBMS_SCHEDULER.SET_ATTRIBUTE`是修改job属性的过程,包括以下参数:
  •    - `name`:job的名称。
  •    - `attribute`:要修改的属性名称,可以是start_date、repeat_interval、end_date等。
  •    - `value`:修改后的属性值,可以是一个日期类型的变量或者表达式。
  • 3. `job_name`是要修改的job的名称。
  • 4. `SYSTIMESTAMP + INTERVAL '1' DAY`表示将job的开始时间修改为当前时间加上1天后的时间。
  • 5. `/`是PL/SQL代码块的竣事标志。
   注意:
  利用DBMS_SCHEDULER包修改job的属性时,必要包管job已经存在。如果job不存在,则必要先利用CREATE_JOB过程创建job,然后再利用SET_ATTRIBUTE过程修改job的属性。
  八、job执行失败 

 job 执行失败大概有多种原因,例如作业的执行时间辩论、作业依赖的对象不存在或无效、作业执行时发生错误等。以下是一些常见的办理方法:


  • 1. 查抄作业的执行时间是否与其他作业辩论,如果辩论则必要调整作业的执行时间。
  • 2. 查抄作业依赖的对象是否存在或有用,如果不存在或无效则必要修复或重新创建这些对象。
  • 3. 查抄作业执行时是否发生了错误,如果发生了错误则必要检察错误日志或调试信息,修复错误并重新执行作业。
  • 4. 查抄作业的执行权限是否正确,如果权限不足则必要授权或修改作业的执行用户。
  • 5. 查抄作业的定时器是否正确,如果定时器不正确则必要修改作业的执行时间或执行间隔。
  • 6. 查抄作业的运行环境是否正确,例如作业依赖的环境变量、路径、配置文件等是否正确设置。
  • 7. 如果以上方法都无法办理问题,则必要进一步分析作业执行的情况,例如检察作业的日志、调试信息、执行计划等,找出问题并修复。
   总结:
  办理  job 执行失败问题必要综合思量多个因素,必要对作业的执行情况进行全面分析和过细调试,才气找到问题并办理。同时,为了避免作业执行失败,必要在设计作业时思量各种大概的情况,并接纳相应的措施来包管作业的正确执行。
  如果一个作业(job)执行失败,Oracle 数据库会根据作业的重试次数和重试间隔时间来进行重试。默认情况下,Oracle 数据库会在作业执行失败后立即进行重试,最多重试 16 次,每次重试的间隔时间为 5 分钟。也就是说,如果一个作业执行失败,Oracle 数据库会在 5 分钟后再次尝试执行该作业,如果该次执行仍然失败,则会继承重试,直到达到最大重试次数为止。
   注意:
  作业的重试次数和重试间隔时间可以通过 DBMS_JOB.CHANGE 或 DBMS_SCHEDULER.SET_ATTRIBUTE 进行修改。用户可以根据实际情况来设置作业的重试次数和重试间隔时间,以便更好地管理作业的执行。同时,如果作业的重试次数和重试间隔时间设置不当,大概会导致作业长时间无法执行或频繁重试,影响体系的稳固性和性能。因此,在设置作业的重试次数和重试间隔时间时必要慎重思量。
  通常情况下: 


  • 1、每次重试时间都是递增的,第一次1分钟,2分钟,4分钟,8分钟 ... 依此类推。
  • 2、当凌驾1440分钟,也就是24小时的时候,固定的重试时间为1天。
  • 3、凌驾16次重试后,job就会被标记为broken,next_date为4000-1-1,也就是不再进行job重试。16次重试的时间大概是7天半。
其中前两条如许设计的目的是为了避免在短时间内频繁地重试,降低体系的负载,同时也可以或许包管使命可以或许在公道的时间内得到处理。
而第三条是由于在 Oracle 中,如果一个作业(job)执行失败达到最大重试次数后,该作业会被标记为 "broken" 状态,同时下一次执行时间会被设置为 4000-01-01,即不再对该作业进行重试。这是 Oracle 数据库的默认行为,旨在防止无限制地重试失败的作业,避免对体系造成过大的负担和风险。
当作业被标记为 "broken" 状态后,用户可以通过调用 DBMS_JOB.BROKEN 过程来修改作业的状态,例如将作业恢复为正常状态、更新作业的下一次执行时间和执行间隔时间等。同时,用户也可以通过修改作业的重试次数和重试间隔时间来避免作业被标记为 "broken" 状态,以便更好地管理作业的执行。
   注意:
  对于那些不必要重试的作业,用户可以将其重试次数设置为 0,以避免对体系造成不必要的负担和风险。
  如果Oracle中出现job重复调用16次的情况,大概是由于job的重试机制导致的。为了避免这种情况,可以思量以下几种办理办法:


  • 1. 修改job的重试次数和重试时间:可以通过修改job的重试次数和重试时间来避免job出现过多的重试。可以将重试次数设置为一个较小的值,例如3次或5次,同时将重试时间设置为一个适当的值,例如每次重试之间间隔5分钟或10分钟。
  • 2. 利用唯一的标识符:可以在job中利用唯一的标识符来避免重复调用。例如,可以在job中设置一个唯一的ID,每次调用时查抄该ID是否已经存在,如果存在则不继承执行,否则执行使命。
  • 3. 利用分布式锁:可以利用分布式锁来避免job重复调用。例如,可以利用Redis中分布式缓存工具来实现分布式锁,每次调用job时先获取锁,执行使命完毕后开释锁,如许可以包管同一时间只有一个job在执行。
  • 4. 利用数据库事务:可以利用数据库事务来避免job重复调用。例如,在job执行前先查抄数据库中是否已经存在相同的记载,如果存在则回滚事务,否则执行使命并提交事务。
我们也可以创建一张空表,用来吸收数据 create table t_k(id number(1)),然后创建一个存过,内里包含真实的存储过程。如下所示:
  1. create or replace pro_写到job中 is
  2. v_cnt number;
  3. begin
  4.   insert into t_k(id) values(1);
  5.   commit;
  6.   select count(1) into v_cnt from t_k;
  7.   if v_cnt=1 then
  8.     pro_真实();
  9.     正确处理;
  10.   else
  11.     错误处理(比如向报错表中插入一条数据;打印错误;raise_application_error报错;发邮件)
  12.   end if;
  13. end;
  14. declare
  15. v_jobid number;
  16. begin
  17.   dbms_job.submit(job   => v_jobid,
  18.                   what  => 'pro_写到job中',
  19.                   next_date  => trunc(sysdate,'dd')+3/24,--第一次执行的时间,夜里三点
  20.                   interval   => 'trunc(sysdate,''dd'')+1');--间隔时间,每天执行
  21.   commit;
  22. end;
复制代码
九、job用法

接下来展示一个完整的job用例!!!
假设我们必要定期清理一个名为CUSTOMER的表中的逾期数据,利用Job来实现。
1. 创建一个PL/SQL块,用于清理逾期数据:
  1. CREATE OR REPLACE PROCEDURE clean_customer_data AS
  2. BEGIN
  3.   DELETE FROM customer WHERE expiration_date < SYSDATE;
  4.   COMMIT;
  5. END;
复制代码
2. 创建一个Job,用于定期执行clean_customer_data存储过程:
  1. BEGIN
  2.   DBMS_SCHEDULER.CREATE_JOB (
  3.     job_name        => 'clean_customer_data_job',
  4.     job_type        => 'STORED_PROCEDURE',
  5.     job_action      => 'clean_customer_data',
  6.     start_date      => SYSDATE,
  7.     repeat_interval => 'FREQ=DAILY; INTERVAL=1',
  8.     enabled         => TRUE,
  9.     comments        => '清理过期数据');
  10. END;
复制代码
其中,job_name是Job的名称,job_type表示Job的类型,可以为STORED_PROCEDURE、PLSQL_BLOCK、EXECUTABLE等。job_action是要执行的使命,可以是存储过程、PL/SQL块、外部程序等。start_date是Job的开始时间,repeat_interval表示Job的重复执行间隔,可以利用各种时间间隔语法。enabled表示Job是否启用,comments是Job的解释。
3. 查抄Job是否正常运行:
  1. SELECT job_name, state, last_start_date, next_run_date
  2. FROM dba_scheduler_jobs
  3. WHERE job_name = 'clean_customer_data_job';
复制代码
该语句可以检察Job的状态、前次执行时间和下次执行时间等信息。
4. 如果必要制止或删除Job,可以利用以下语句:
制止Job:
  1. BEGIN
  2.   DBMS_SCHEDULER.STOP_JOB (
  3.     job_name        => 'clean_customer_data_job',
  4.     force_option    => 'IMMEDIATE',
  5.     commit_semantics=> 'ABORT');
  6. END;
复制代码
删除Job:
  1. BEGIN
  2.   DBMS_SCHEDULER.DROP_JOB (
  3.     job_name   => 'clean_customer_data_job',
  4.     force      => TRUE);
  5. END;
复制代码
以上就是一个简单的Job的利用示例,通过Job可以实现各种定时使命,提高数据库的自动化管理能力。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表