2016-12-26 19 views
5

Tôi đã tạo ra các chương trình tiếp theo và tiếp theo VIỆC Oracle:Làm thế nào để tạo ra một công việc Oracle async để chạy trong nhiều trường hợp

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; 
/

Bây giờ, tôi có một người dùng có thể chạy/thực hiện công việc mà các cuộc gọi thủ tục tiếp theo :

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; 

Các sự cố của tôi ở đây là gì?

  • Tôi cần chạy công việc ở chế độ không đồng bộ. Đó là lý do tại sao tôi có một số enable hoặc run_job sử dụng thông số USE_CURRENT_SESSION FALSE. Tôi nghĩ rằng điều này hoạt động.
  • Tôi cần thực hiện nhiều phiên bản của cùng một công việc, bắt đầu bằng người dùng khác nhau, cùng một lúc. Ví dụ: người dùng A gọi thủ tục runJOB. Công việc có thể chạy trong 20 giây. Trong 20 giây này, người dùng B có thể gọi cùng một quy trình, trong một phiên khác. Đó là lý do tại sao tôi đã cố gắng sử dụng thuộc tính PARALLEL_INSTANCES, nhưng Tôi chỉ nhận được một lần thực thi. Tôi nghĩ rằng Oracle thấy rằng công việc là đang chạy, vì vậy hãy loại bỏ lần thử thứ hai để chạy.

Trong khi tiếp tục, tôi cần một công việc phải được thực hiện ở chế độ không đồng bộ và với nhiều phiên bản cùng một lúc.

Sau khi thực thi "kép" của công việc cho hai trường hợp tôi chỉ nhận được một bản ghi trong bảng user_SCHEDULER_JOB_RUN_DETAILS, nhưng 2 cho phép công việc của hai người dùng khác nhau (SGSS và 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) 

Bất kỳ sự giúp đỡ?

Lưu ý: tôi không thể có tên gọi khác nhau công việc như trong giải pháp này (How run two or more instances of an oracle job in the same time?), bởi vì công việc đã được tạo ra và những người dùng gọi công việc này không có quyền tạo.

Trả lời

1

Giải pháp: 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; 

Trong gói:

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);

bây giờ, kiểm tra documentation:

này quy định hay không chạy việc sẽ xảy ra trong cùng một phiên rằng thủ tục được gọi từ.

Khi use_current_session được đặt là TRUE:

  • Công việc chạy như người dùng đã gọi RUN_JOB, hoặc trong trường hợp của một công việc bên ngoài địa phương và có chứng nhận, người dùng có tên trong chứng chỉ
    .

  • Bạn có thể kiểm tra công việc và xem mọi lỗi có thể xảy ra trên dòng lệnh.

  • run_count, last_start_date, last_run_duration và failure_count không được cập nhật.

  • RUN_JOB có thể chạy song song với công việc thường xuyên theo lịch trình.

Khi use_current_session được thiết lập để FALSE:

  • Công việc chạy như người sử dụng là người chủ sở hữu công việc.

  • Bạn cần kiểm tra nhật ký công việc để tìm thông tin lỗi.

  • run_count, last_start_date, last_run_duration và failed_count được cập nhật.

  • RUN_JOB không thành công nếu công việc được lên lịch thường xuyên đang chạy.

+0

Cảm ơn, nhưng sử dụng FALSE là những gì mà tôi đã đưa tin. Tôi cần phải bắt đầu một ví dụ công việc mới ngay cả khi một cá thể khác đang chạy. Hãy để tôi thử giá trị TRUE với một chút thay đổi ở đây. – milheiros

+0

Nếu tôi sử dụng TRUE tôi không thể thực hiện công việc không đồng bộ. Với FALSE tôi không thể có nhiều lần thực thi cùng một công việc – milheiros

+1

Đúng, nếu bạn cần thực thi song song, bạn nên đọc về Hàng đợi (ví dụ: https://oracle-base.com/articles/10g/scheduler-enhancements-10gr2) – Stawros

Các vấn đề liên quan