无法理解APEX_MAIL的工作如何运作

时间:2018-03-17 23:46:24

标签: oracle plsql oracle11g oracle-apex dbms-scheduler

我目前正在尝试实现类似版本的oracle的APEX_MAIL包。我有一切工作,但除非我修改它,否则我无法完成工作。

APEX_MAIL使用的作业称为ORACLE_APEX_MAIL_QUEUE

BEGIN
DBMS_SCHEDULER.set_attribute( name => '"APEX_040000"."ORACLE_APEX_MAIL_QUEUE"', attribute => 'job_action', value => 'APEX_040000.WWV_FLOW_MAIL.PUSH_QUEUE');

DBMS_SCHEDULER.set_attribute( name => '"APEX_040000"."ORACLE_APEX_MAIL_QUEUE"', attribute => 'number_of_arguments', value => '2');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( 
         job_name => '"APEX_040000"."ORACLE_APEX_MAIL_QUEUE"', 
         argument_position => 1, 
         argument_value => '');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( 
         job_name => '"APEX_040000"."ORACLE_APEX_MAIL_QUEUE"', 
         argument_position => 2, 
         argument_value => '');

END; 
/

所以我去包看看代码的作用。我假设推送队列会在队列中发送电子邮件。相反,它再次调用相同的工作!

PROCEDURE PUSH_QUEUE( P_SMTP_HOSTNAME IN VARCHAR2 DEFAULT NULL,
                      P_SMTP_PORTNO   IN VARCHAR2 DEFAULT NULL )
IS
BEGIN
    PUSH_QUEUE_BACKGROUND;
END PUSH_QUEUE;


PROCEDURE PUSH_QUEUE_BACKGROUND
IS
BEGIN
    SYS.DBMS_SCHEDULER.RUN_JOB( JOB_NAME => 'ORACLE_APEX_MAIL_QUEUE', USE_CURRENT_SESSION => FALSE );
EXCEPTION
    WHEN OTHERS THEN
        IF SQLCODE <> -27478 THEN
            RAISE;
        END IF;
END PUSH_QUEUE_BACKGROUND;

所以基本上这个工作什么都不做,但我把它切换到调用PUSH_QUEUE_IMMEDIATE来做我认为应该做的事情。

PROCEDURE PUSH_QUEUE_IMMEDIATE( P_FORCE_YN IN VARCHAR2 DEFAULT 'N')
IS
    L_STATUS            NUMBER;
    L_LOCK_HDL          VARCHAR2(128);
    E_DB_SHUTDOWN       EXCEPTION;
    PRAGMA EXCEPTION_INIT(E_DB_SHUTDOWN, -1089);
BEGIN



    WWV_FLOW_DEBUG.ENABLE_DBMS_OUTPUT;



    SYS.DBMS_LOCK.ALLOCATE_UNIQUE( LOCKNAME => 'APEX_MAIL_QUEUE_LOCK', LOCKHANDLE => L_LOCK_HDL);
    L_STATUS := SYS.DBMS_LOCK.REQUEST( LOCKHANDLE        => L_LOCK_HDL,
                                   LOCKMODE          => SYS.DBMS_LOCK.X_MODE,
                                   TIMEOUT           => 0,
                                   RELEASE_ON_COMMIT => FALSE );
    WWV_FLOW_DEBUG.INFO('APEX Mail Lock status: ' || L_STATUS );




    IF L_STATUS = 0 THEN

        FOR C1 IN ( SELECT   ID, MAIL_SEND_COUNT, LAST_UPDATED_ON
                      FROM WWV_FLOW_MAIL_QUEUE
                     ORDER BY MAIL_SEND_COUNT, LAST_UPDATED_ON) LOOP
            BEGIN
                WWV_FLOW_DEBUG.INFO( 'Pushing email: ' || C1.ID );







                IF  (C1.MAIL_SEND_COUNT = 0) OR (NVL(P_FORCE_YN,'N') = 'Y') OR
                   (C1.MAIL_SEND_COUNT > 0 AND (POWER(2,C1.MAIL_SEND_COUNT)/(60*24) + C1.LAST_UPDATED_ON) < SYSDATE) THEN
                    BACKGROUND( P_ID => C1.ID );
                END IF;
                WWV_FLOW_DEBUG.INFO( 'Pushed email: ' || C1.ID );
            EXCEPTION
                WHEN OTHERS THEN
                    WWV_FLOW_DEBUG.LOG_EXCEPTION;

                    IF L_LOCK_HDL IS NOT NULL THEN
                        L_STATUS := SYS.DBMS_LOCK.RELEASE( L_LOCK_HDL );
                        WWV_FLOW_DEBUG.INFO('APEX Mail released lock' );
                    END IF;
            END;
        END LOOP;
    END IF;



    IF L_LOCK_HDL IS NOT NULL THEN
        L_STATUS := SYS.DBMS_LOCK.RELEASE( L_LOCK_HDL );
        WWV_FLOW_DEBUG.INFO('APEX Mail released lock' );
    END IF;
EXCEPTION WHEN E_DB_SHUTDOWN THEN 
    NULL;
END PUSH_QUEUE_IMMEDIATE;

我正在尝试将APEX_MAIL复制到一个点,但如果我这样做,我将无法找到合适的工作。任何人都可以指出APEX_MAIL是否会在应用程序设置更改或任何其他更改后更改作业的作用?

提前致谢!

1 个答案:

答案 0 :(得分:1)

APEX_MAIL.PUSH_QUEUE可用于您自己的代码,以立即发送您的邮件(在队列中)。该作业通常调用PUSH_QUEUE_IMMEDIATE。我不知道您的设置是否是安装中的错误或您网站上的错误。 因此,它在一个单独的会话中将PUSH_QUEUE_IMMEDIATE称为APEX_040000作业。

由于每个人都可以请求立即发送队列中的所有作业,因此通过SYS.DBMS_LOCK.REQUEST确保只有一个会话实际上会进行传输。