2012-07-29 74 views
0

我有一個程序發送電子郵件,並從其他功能和程序(主要用於發送警報和通知)調用此過程。程序發送郵件提醒

我面對的一個問題是,如果我們的郵件服務器關閉,然後調用函數或過程停止執行,我的意思是他們不做任何他們應該做的功能。我如何確保調用函數或過程,或者對於那些調用 MailProcedure的客戶端,即使在郵件服務器關閉時也應該執行其功能。

我該如何做到這一點? 任何幫助都非常明顯。

郵件程序

CREATE OR REPLACE PROCEDURE MailProcedure(frm_id IN VARCHAR2, to_id IN VARCHAR2, subject IN VARCHAR2, body_text IN VARCHAR2) 
AS 
c utl_tcp.connection; 
rc integer; 
BEGIN 
c := utl_tcp.open_connection('email_server', 25); 
rc := utl_tcp.write_line(c, 'string'); 
rc := utl_tcp.write_line(c, 'from address'); 
rc := utl_tcp.write_line(c, 'to address'); 
rc := utl_tcp.write_line(c, 'Subject'); 
rc := utl_tcp.write_line(c, 'body'); 
utl_tcp.close_connection(c); 
EXCEPTION 
    WHEN OTHERS 
    THEN 
     null; 
END; 
/
+0

如果郵件服務器發生故障,您希望發生什麼?你想讓來電成功,並且不發送電子郵件嗎?你想讓電子郵件排隊以備後用嗎?還有別的嗎?如果'MailProcedure'確實有'WHEN OTHERS THEN'異常處理程序,它是如何導致調用程序失敗的?正如所寫的,'MailProcedure'只會默默地失敗,這可能不是最好的解決方案,但肯定不應該引發異常被調用者。 – 2012-07-29 18:03:07

+0

如果郵件服務器關閉,則不會發送要發送的郵件,並希望排隊以備後用。我怎樣才能做到這一點?。謝謝 – user75ponic 2012-07-30 01:56:42

回答

3

因爲要排隊以便稍後傳遞的郵件,最簡單的辦法是異步發送的所有電子郵件。您的其他程序將調用一個QueueMail程序插入行到新mail_queue

CREATE OR REPLACE PROCEDURE QueueMail(p_from IN VARCHAR2, 
             p_to IN VARCHAR2, 
             p_subject IN VARCHAR2, 
             p_body IN VARCHAR2) 
AS 
BEGIN 
    INSERT INTO mail_queue(mail_queue_id. from, to, subject, body) 
    VALUES(mail_queue_seq.nextval, p_from, p_to, p_subject, p_body); 
END; 

那麼你將不得不在一個單獨的線程實際感知的電子郵件,並從隊列中刪除的消息運行一個獨立的過程。類似於

CREATE OR REPLACE PROCEDURE SendQueuedMessages 
AS 
BEGIN 
    FOR msg IN (SELECT * FROM mail_queue) 
    LOOP 
    sendMessage(msg.from, msg.to, msg.subject, msg.body); 
    DELETE FROM mail_queue 
    WHERE mail_queue_id = msg.mail_queue_id; 
    commit; 
    END LOOP; 
END; 

其中sendMessage實現發送電子郵件的實際邏輯。我認爲你會想要使用utl_mailutl_smtp包發送電子郵件,而不是使用utl_tcp,但當然,您可以使用utl_tcp。然後,您可以使用dbms_jobdbms_scheduler程序包安排SendQueuedMessages程序。這樣

DECLARE 
    l_jobno PLS_INTEGER; 
BEGIN 
    dbms_job.submit(l_jobno, 
        'BEGIN SendQueuedMessages; END;', 
        sysdate + interval '1' minute, 
        'sysdate + interval ''1'' minute'); 
    commit; 
END; 

的事情會創建一個運行的程序SendQueuedMessages每分鐘的工作。如果郵件服務器關閉,則SendQueuedMessage過程失敗,並且作業會自動重新計劃以後運行。第一次失敗後,作業在1分鐘後再次運行。第二次失敗後,運行2分鐘後,然後運行4分鐘,8分鐘等,直到連續失敗16次。如果您想要捕獲SendQueuedMessages過程中的例外情況,您可以選擇默認行爲以外的其他方式。由於作業失敗導致無法寫入警報日誌,因此您的DBA可能會要求您處理異常並處理重新調度作業,以避免將不必要的數據寫入警報日誌。

+0

感謝賈斯汀您的神話般的答案。我會在特定時間完成工作。非常感激。 – user75ponic 2012-08-06 07:16:12