2016-12-26 10 views
5

я создал следующую программу и последующую Oracle РАБОТУ:Как создать асинхронную Oracle задание для выполнения в нескольких экземплярах

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; 

В чем мои проблемы?

  • Мне нужно запустить работу в асинхронном режиме. Вот почему у меня есть enable или run_job с использованием параметра USE_CURRENT_SESSION FALSE. Я думаю, что это работает.
  • Мне нужно выполнить несколько экземпляров одного и того же задания, начиная с разных пользователей, в то же время. Например, пользователь A вызывает процедуру runJOB. Задание может выполняться через 20 секунд. В этом случае 20 секунд пользователь B может вызывать ту же процедуру в другом сеансе. Вот почему я попытался использовать атрибут PARALLEL_INSTANCES, но Я получаю только одно исполнение. Я думаю, Oracle видит, что работа работает, поэтому отмените вторую попытку запуска.

При возобновлении работы мне необходимо выполнить задание, которое должно выполняться в режиме асинхронного режима и с несколькими экземплярами одновременно.

После «двойной» выполнение задания для двух случаев я получаю только одну запись в таблице user_SCHEDULER_JOB_RUN_DETAILS, но 2 включить работу для двух разных пользователей (SGSS и EX01882_BD)

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?), потому что работа уже создана, и пользователи, которые называют эту работу, не имеют права на создание.

ответ

1

Решение: 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; 
1

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

теперь проверить documentation:

Это определяет, следует ли задание запуска происходит в одной и той же сессии , что процедура была вызвана из.

Когда use_current_session установлен в TRUE:

  • Задание выполняется как пользователь, который называется RUN_JOB, или в случае локального внешнего задания с учетными данными, пользователь с именем в
    удостоверения.

  • Вы можете проверить работу и увидеть возможные ошибки в командной строке.

  • run_count, last_start_date, last_run_duration и fail_count не обновляются.

  • RUN_JOB может запускаться параллельно с регулярным расписанием работы.

Когда use_current_session установлен в FALSE:

  • Работа работает как пользователь, который является владельцем задания.

  • Чтобы найти информацию об ошибке, вам необходимо проверить журнал заданий.

  • run_count, last_start_date, last_run_duration и fail_count обновляются.

  • RUN_JOB не работает, если выполняется регулярное задание.

+0

Спасибо, но с использованием FALSE что, который я уже сообщал. Мне нужно запустить новый экземпляр задания, даже если работает другой экземпляр. Позвольте мне попробовать значение TRUE с небольшим изменением здесь. – milheiros

+0

Если я использую TRUE, я не могу выполнить выполнение асинхронного задания. С FALSE Я не могу иметь несколько исполнений одного и того же задания – milheiros

+1

Да, если вам действительно нужно выполнить параллельное выполнение, вы должны прочитать о очередях (например: https://oracle-base.com/articles/10g/scheduler-enhancements-10gr2) – Stawros

 Смежные вопросы

  • Нет связанных вопросов^_^