【问题标题】:How to create a async Oracle job to run in multiple instances如何创建异步 Oracle 作业以在多个实例中运行
【发布时间】:2017-01-06 19:50:15
【问题描述】:

我已经创建了下一个程序和后续的 Oracle JOB:

BEGIN
   DBMS_SCHEDULER.create_program (program_name          => 'myProg',
                                  program_action        => 'myProc',
                                  program_type          => 'STORED_PROCEDURE',
                                  number_of_arguments   => 3,
                                  enabled               => FALSE);

   DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                           argument_position   => 1,
                                           argument_type       => 'NUMBER');

   DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                           argument_position   => 2,
                                           argument_type       => 'NUMBER');

   DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                           argument_position   => 3,
                                           argument_type       => 'NUMBER',
                                           DEFAULT_VALUE       => NULL);

   DBMS_SCHEDULER.create_job ('myJob',
                              program_name   => 'myProg',
                              enabled        => FALSE,
                              comments       => 'Send data');

   DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob', 'PARALLEL_INSTANCES', TRUE);
   DBMS_SCHEDULER.SET_ATTRIBUTE ('myJob',
                                 'logging_level',
                                 DBMS_SCHEDULER.LOGGING_FULL);
END;
/

现在,我有一个用户可以运行/执行调用下一个过程的作业:

    PROCEDURE runJOB(param1   IN PLS_INTEGER,
                  param2   IN PLS_INTEGER DEFAULT NULL,
                  param3   IN PLS_INTEGER DEFAULT NULL)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   DBMS_SCHEDULER.enable ('myProg');

   DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
   DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
   DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
   --DBMS_SCHEDULER.enable ('myJob');
   DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION => FALSE);
--DBMS_SCHEDULER.disable ('myJob');
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END runJOB;

我有什么问题?

  • 我需要以异步模式运行作业。这就是为什么我有一个 enablerun_job 使用 USE_CURRENT_SESSION 参数 FALSE。我认为这行得通。
  • 我需要执行同一个作业的多个实例,从 不同的用户,同时。例如,用户 A 调用 runJOB 程序。该作业可以在 20 秒内运行。在这 20 秒,用户 B 可以在不同的会话中调用相同的过程。 这就是为什么我尝试使用 PARALLEL_INSTANCES 属性,但是 我只有一次处决。我认为甲骨文认为这份工作是 正在运行,因此请放弃第二次尝试运行。

在恢复时,我需要一个必须以异步模式执行并同时使用多个实例的作业。

在为两个实例执行“双重”作业后,我在user_SCHEDULER_JOB_RUN_DETAILS 表中只获得了一条记录,但为两个不同的用户(SGSS 和 EX01882_BD)启用了 2 条记录

52367532    26/12/2016 12:08:44,584878 +00:00   SGSS    myJob DEFAULT_JOB_CLASS RUN SUCCEEDED                               (HugeClob)
52364238    26/12/2016 12:08:36,529539 +00:00   SGSS    myJob DEFAULT_JOB_CLASS ENABLE      EX01882_BD                          (HUGECLOB)
52367534    26/12/2016 12:08:34,302807 +00:00   SGSS    myJob DEFAULT_JOB_CLASS ENABLE      SGSS                            (HUGECLOB)

有什么帮助吗?

注意: 我不能在此解决方案中使用不同的作业名称 (How run two or more instances of an oracle job in the same time?),因为该作业已创建并且调用此作业的用户没有创建权限。

【问题讨论】:

    标签: oracle scheduler oracle12c job-scheduling


    【解决方案1】:

    DBMS_SCHEDULER.RUN_JOB (JOB_NAME => 'myJob', USE_CURRENT_SESSION => 错误);

    现在,检查documentation

    这指定作业运行是否应在同一 调用该过程的会话。

    当 use_current_session 设置为 TRUE 时:

    • 作业以调用 RUN_JOB 的用户身份运行,或者在具有凭据的本地外部作业的情况下,以在
      中指定的用户身份运行 凭证。

    • 您可以测试作业并在命令行上查看任何可能的错误。

    • run_count、last_start_date、last_run_duration 和 failure_count 未更新。

    • RUN_JOB 可以与定期安排的作业运行并行运行。

    当 use_current_session 设置为 FALSE 时:

    • 作业以作业所有者的用户身份运行。

    • 您需要查看作业日志以查找错误信息。

    • run_count、last_start_date、last_run_duration 和 failure_count 已更新。

    • 如果定期安排的作业正在运行,则 RUN_JOB 会失败。

    【讨论】:

    • 谢谢,但使用 FALSE 是我已经报告过的。即使另一个实例正在运行,我也需要启动一个新的作业实例。让我在这里稍微改变一下 TRUE 值。
    • 如果我使用 TRUE,我将无法执行异步作业。使用 FALSE 我不能多次执行同一个作业
    • 是的,如果您需要真正的并行执行,您应该阅读队列(例如:oracle-base.com/articles/10g/scheduler-enhancements-10gr2
    【解决方案2】:

    解决方案:Event-Based Jobs

    GRANT AQ_ADMINISTRATOR_ROLE TO USERA;
    GRANT EXECUTE ON DBMS_SCHEDULER TO USERA;
    GRANT EXECUTE ON sys.DBMS_SCHEDULER TO USERA;
    GRANT EXECUTE ON sys.DBMS_ISCHED TO USERA;
    GRANT CREATE JOB TO USERA;
    GRANT CREATE EXTERNAL JOB TO USERA;
    
    CREATE OR REPLACE TYPE t_event_queue_payload AS OBJECT (
      event_name  VARCHAR2(30)
    );
    
    BEGIN
       -- Create a queue table to hold the event queue.
       DBMS_AQADM.create_queue_table (
          queue_table          => 'event_queue_tab',
          queue_payload_type   => 't_event_queue_payload',
          multiple_consumers   => TRUE,
          comment              => 'Comments');
    
       --Create the event queue.
       DBMS_AQADM.create_queue (queue_name    => 'event_queue',
                                queue_table   => 'event_queue_tab');
    
       -- Start the event queue.
       DBMS_AQADM.start_queue (queue_name => 'event_queue');
    END;
    /
    
    
    BEGIN
       DBMS_SCHEDULER.create_program (
          program_name          => 'myProg',
          program_action        => 'USERA.PACKAGE.myProc',
          program_type          => 'STORED_PROCEDURE',
          number_of_arguments   => 3,
          enabled               => FALSE);
    
       DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                               argument_position   => 1,
                                               argument_type       => 'NUMBER');
    
       DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                               argument_position   => 2,
                                               argument_type       => 'NUMBER');
    
       DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT (program_name        => 'myProg',
                                               argument_position   => 3,
                                               argument_type       => 'NUMBER',
                                               DEFAULT_VALUE       => NULL);
    
       DBMS_SCHEDULER.enable ('myProg');
       DBMS_SCHEDULER.create_job (
          'myJob',
          program_name      => 'myProg',
          comments          => 'StartJob',
          auto_drop         => FALSE,
          start_date        => SYSTIMESTAMP,
          event_condition   => 'tab.user_data.event_name = ''give_me_a_prod''',
          queue_spec        => 'event_queue',
          enabled           => FALSE);
    
       COMMIT;
    END;
    /
    
    PROCEDURE enqueue(param1   IN PLS_INTEGER,
                      param2   IN PLS_INTEGER DEFAULT NULL,
                      param3   IN PLS_INTEGER DEFAULT NULL)
    IS
       PRAGMA AUTONOMOUS_TRANSACTION;
       l_enqueue_options      DBMS_AQ.ENQUEUE_OPTIONS_T;
       l_message_properties   DBMS_AQ.MESSAGE_PROPERTIES_T;
       l_message_handle       RAW (16);
       l_queue_msg            t_event_queue_payload;
    BEGIN
       l_queue_msg := t_event_queue_payload ('give_me_a_prod');
    
       -- Define arguments
       DBMS_SCHEDULER.set_job_argument_value ('myJob', 1, TO_CHAR (param1));
       DBMS_SCHEDULER.set_job_argument_value ('myJob', 2, TO_CHAR (param2));
       DBMS_SCHEDULER.set_job_argument_value ('myJob', 3, TO_CHAR (param3));
    
       DBMS_AQ.enqueue (queue_name           => 'USERA.event_queue',
                        enqueue_options      => l_enqueue_options,
                        message_properties   => l_message_properties,
                        payload              => l_queue_msg,
                        msgid                => l_message_handle);
    
       COMMIT;
    EXCEPTION
       WHEN OTHERS
       THEN
          DBMS_OUTPUT.put_line (
             SQLERRM || ' - ' || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
    END enqueue;
    

    包装内:

    PROCEDURE myProc(param1   IN PLS_INTEGER,
                      param2   IN PLS_INTEGER DEFAULT NULL,
                      param3   IN PLS_INTEGER DEFAULT NULL)
    IS
       PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
    ...
       PKG_SAP_FSCD_INTERRECIBOS.callSomething.... 
    ...
    
    END myProc;
    

    【讨论】:

      猜你喜欢
      • 2019-02-10
      • 2015-01-27
      • 1970-01-01
      • 2010-11-05
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多