0

電子メールを送信するプロシージャがあり、このプロシージャは他の関数やプロシージャから呼び出されています(主にアラートと通知の送信に使用されます)。

私が直面している問題の1つは、メールサーバーがダウンしている場合、関数またはプロシージャを呼び出すと実行が停止することです。つまり、本来の機能を実行しないということです。関数やプロシージャの呼び出し、さらに言えば、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;
/
4

1 に答える 1

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_mailまたはパッケージを使用して電子メールを送信することをお勧めしますが、もちろん、を使用することもできます。次に、またはパッケージのいずれかを使用して手順をスケジュールします。このようなものutl_smtputl_tcputl_tcpSendQueuedMessagesdbms_jobdbms_scheduler

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回目の失敗の後、2分後に実行され、その後4分、8分など、16回連続して失敗するまで実行されます。SendQueuedMessagesプロシージャで例外をキャッチする場合は、デフォルトの動作以外のものを選択できます。ジョブの失敗によりアラートログへの書き込みに失敗するため、DBAは、アラートログに不要なデータが書き込まれないように、例外の処理とジョブの再スケジュールの処理を要求する場合があります。

于 2012-07-30T06:33:24.650 に答える