2011-01-17 10 views
0

アプリのユーザーにメールを送信して、すべてのメールが1回だけ送信されるようにします。 私は電子メールの送信をデータベースに記録します。私はこの操作の順序を使用する場合 : PHPとMySQLで電子メールをトランザクションにする方法を教えてください。

  • データベース送信メールに

    1. 挿入を
    2. はコミットチャンスだけ(ステップ#電子メールを送信した後に出て、そのスクリプトの時間があり

    2 )、コミットを行う前に(ステップ#3)。その場合、ステップ1の変更はコミットされず、電子メール送信ジョブは、同じ電子メールが再び送信されるように電子メールが前回正常に送信されたことを知ることができません。

    メールが途切れることはありますか?またはメールを重複して送信する必要がありますか?

  • +0

    なぜDB経由で送信されたメールを追跡しないのですか?あなたは電子メールを再送しないように?また、例外処理 'try/catch'メソッドでタイムアウトを処理するようにしてください。 – Jakub

    +0

    @Jakub、Webサーバーが起動したスクリプトが長時間実行されていると判断した場合、スクリプトのタイムアウトを参照していました。私はこのシナリオでtry/catchが役立つかどうかわかりません –

    +0

    あなたはそれがタイムアウトになっていることをどのような電子メールで送信していますか?または、これは単にあなたがいくつかの電子メールで気づいた副作用ですか?好奇心と、そのシナリオで試して/キャッチは助けにはならないでしょう。 – Jakub

    答えて

    0

    ちょっと自分の疑問を考える時間がありました。ここで私は今何を考えている:

    問題の手順を送信する電子メールは以下の通りであった。

    1. データベース
    2. に挿入し、電子メールに
    3. を送るので、メールがトランザクションにすることはできません

    をコミットステップ#2(上記)は、トランザクションがアクティブである間に完了しても、トランザクションの一部ではありません。

    これらの手順を実行すると、失敗した電子メール送信試行が再試行されますが、電子メールが複数回送信されないことを保証することはできません。この状況は、電子メール送信エンジンがトランザクション対応である場合にのみ向上する可能性があります。このようなエンジンは、(少なくとも)次の操作を行います:

    1. は、電子メールのジョブ投入を受け入れるが、コミットが
    2. 実行されるまで電子メールが送信されない場合、コミットが失敗してください電子メールを送信しません。トランザクションはロールバックされている場合
    3. が投入されたジョブをキャンセルし

    私はそのような電子メールサーバーを認識していないです。彼のanswer

    Nishantは、次の手順を提案:

    1. は、メールを送信する前にデータを挿入します。状態を送信に設定する
    2. メールを送信するには、手順(2)の結果に基づいて
    3. に基づいて、行を失敗または送信に更新します。上述のように

    これらの手順はまた、同じ理由で、スクリプトのタイムアウトに電子メールの送信の重複を確保することはできません。

    これまでのところ、私はちょうど重複した電子メールで生きなければならないと思う。

    1

    だけでなく、あなたが今sending, failed, sent_successfully

    を表す値とenumまたはintすることができ、列statusを作ることができ、あなたがこれを行う:

    1. は、メールを送信する前にデータを挿入します。ステップにおける結果に基づいてメール
    2. を送信sending
    3. statusを設定(2)、update行のいずれかfailed又はsent_successfully

    また、カラムtriestries < TRY_THRESHOLD場合、30分ごとにfailedメールを送信し、バッチプロセスを持っているのが好きかもしれません。その後、statusfailed_permanentlyまたはsent_successfullyに設定し、エラーをログに記録します。

    2

    これにMySQLトランザクションを使用することができます。基本的には、すべてのクエリを準備し、実行するように指示したときにクエリを実行します。

    メールを送信する前にクエリを準備し、送信後にクエリをコミットします。

    http://dev.mysql.com/doc/refman/5.0/en/commit.html

    詳細情報は、別の方法としては、保留中としてメールを設定し、後に完成として、それを更新することができます。その後、一定時間実行されている保留中のジョブを終了させるcronジョブを実行するか、またはそれらを再処理しようとします。

    3

    短いストーリーを作るには:あなたは電子メールで取引することはできません

    ご存知のように、あなたのSMTPサーバはあなたのメッセージの送信要求を受け取りました。しかし、それが送信されたか、受信されたか、またはバウンスされたかどうかを知る方法はありません。

    これまでにお伝えしたように、あなたの最善の賭けは、時折二重の電子メールを生きることです。それはとにかく非常にまれな出来事になります。

    関連する問題