1

マルチスレッドとスレッド プールの使用に関する概念を理解しています。私が理解しようとしている概念の 1 つは、各スレッドでどのメールが送信されたかを追跡する方法です。各スレッドが x 個のレコードを取得し、それらのメールを反復処理し、メール テンプレートを適用して、ピックアップ ディレクトリにメールを保存する役割を担っていると想像してください。明らかに、別のスレッドと同じデータをプルしないように各スレッドに指示する方法が必要です。

私が考えていた解決策の 1 つは、データをページングし、既に送信されたページを追跡するためのグローバル変数または配列を用意し、各スレッドにその変数を調べて、次の使用可能なページから開始することでした。私が考えることができる唯一の問題は、データが変更された場合、利用可能なページが同期しなくなる可能性があることです.

別の解決策は、データベースにブール値を設定して、アカウントが電子メールで送信されたかどうかを判断することです。したがって、EF は X 個のレコードを取得し、それらのレコードを電子メールで送信する準備ができているものとして更新します。このようにして、各クエリは、電子メールを送信する準備ができていない電子メールのみを検索します。

可能であれば、他の提案を得るか、提供したソリューションを拡張したかった.

4

2 に答える 2

3

いつか複数のアプリサーバーに拡張したいと思うかもしれないことを考えると、メモリ同期の実装は、電子メールが複製されないことを保証するのに十分ではないかもしれません。

解決する最も簡単な方法の1つは、データベースレベルでバッチ処理メカニズムを実装することです。

作業単位の下で

  • Pessimistic Lockingを使用してNxレコードを読み取ります(つまり、同じ電子メールをプルする他のスレッドによる同時読み取りを防止します)
  • これらのレコードにバッチID(またはIsProcessedインジケーター)をスタンプします
  • レコードをアプリに返します

たとえば、SQLサーバーでのバッチPROCは、次のようになります(PKEmailIdと処理済みインジケーターBITフィールドを持つテーブル=dbo.Emailsと仮定IsProcessed):

CREATE PROC dbo.GetNextBatchOfEmails
AS
    BEGIN
        -- Identify the next N emails to be batched. UPDLOCK is to prevent another thread batching same emails
        SELECT top 100 EmailId 
        INTO #tmpBatch
            FROM dbo.Emails WITH (UPDLOCK)
            WHERE IsProcessed = 0

        -- Stamp emails as sent. Assumed that PROC is called under a UOW. The batch IS the UOW
        UPDATE e
            SET e.IsProcessed = 1
            FROM dbo.Emails e
            INNER JOIN #tmpBatch t
                on e.EmailId = t.EmailId

        -- Return the batch of emails to caller
        SELECT e.*
            FROM dbo.Emails e
            INNER JOIN #tmpBatch t
                on e.EmailId = t.EmailId
    END

次に、PROCをEメールエンティティにマップされたEF関数インポートとして公開します。tsの下でTransactionScope、EF関数のインポートを呼び出して電子メールを送信し、成功するとts.Complete()を呼び出すことができます。

于 2012-08-26T16:01:56.377 に答える
2

nonnb の方法に加えて、SQL Server 2005 以降を使用している場合は、必要に応じて 1 つのステートメントですべてを実行できます。

;WITH q AS
(
   SELECT TOP 10 * 
   FROM dbo.your_queue_table
   WHERE
       IsProcessing = 0
   --you can obviously include more filtering criteria to meet your needs
)

UPDATE q WITH (ROWLOCK, READPAST)
SET IsProcessing = 1
OUTPUT INSERTED.*

また、データベース テーブルをキューとして使用することに関する優れた情報もここにあります。

于 2012-08-26T16:27:30.450 に答える