1

次の機能を実現するために、.Net 4.0 の C# で Windows サービスを作成しています。
毎晩設定された時刻に、アプリは SQL Server に接続し、ユーザー テーブルを開き、レコードごとにユーザーの IP アドレスを取得し、WCF 呼び出しを行います。ユーザーの PC に送信して、トランザクションに使用できるかどうかを判断し、State テーブルにレコードを挿入します (y/n と、存在する場合はエラー)。

すべてのユーザーが処理されると、アプリは、IsPcAvailable = true である State テーブルの各レコードを読み取り、別のテーブルからそのユーザーのレポートのリストを取得し、レポートごとにエンタープライズ ドキュメント リポジトリからレポートをフェッチし、ユーザーの PC を呼び出します。 WCF はレポートをハードドライブにプッシュし、状態テーブルを成功に更新します。

上記のシナリオは、1 つのアプリ サーバーでシングル スレッドで実行されている場合、コーディングが簡単です。ただし、冗長性とパフォーマンスのために、少なくとも 2 つのアプリ サーバーがまったく同じことを同時に実行します。

レポートを取得して全国の PC にプッシュするのは時間のかかるプロセスであるため、各ユーザーが最初に User テーブル、次に State テーブル (同じ問題) で 1 回だけ処理されるようにするにはどうすればよいでしょうか。また、アプリをマルチスレッド化するのが最適です。たとえば、2 つのサーバーで 10 のスレッドを実行してすべてのユーザーを処理します。


私はデータベースの第一人者ではないので、C# ソリューションを好むでしょう :) 私の問題に最も近いのは次のとおりです
。 1 層下に移動して ADO.net を使用する必要がありますか?

4

2 に答える 2

1

http://rusanu.com/2010/03/26/using-tables-as-queues/のテクニックを使用することをお勧めします。これは、現時点での優れた読み物です。

これがFIFOのSQLです

create procedure usp_dequeueFifo
as
  set nocount on;
  with cte as (
    select top(1) Payload
      from FifoQueue with (rowlock, readpast)
    order by Id)
  delete from cte
    output deleted.Payload;
go

そしてヒープ用に1つ(順序は関係ありません)

create procedure usp_dequeueHeap 
as
  set nocount on;
  delete top(1) from HeapQueue with (rowlock, readpast)
      output deleted.payload;      
go

これはとても美しく読みますそのほとんど詩

于 2012-06-07T22:22:18.320 に答える
1

各アプリケーション サーバーに共通テーブル (work_queue) をポーリングさせるだけで済みます。共通のテーブル式を使用して行を読み取り/更新できるため、それらが互いに踏み込まないようにすることができます。

;WITH t AS
(
    SELECT TOP 1 * 
    FROM work_queue WHERE NextRun <= GETDATE()
    AND IsPcAvailable = 1
)
UPDATE    t  WITH (ROWLOCK, READPAST)
SET
     IsProcessing = 1,
     MachineProcessing = 'TheServer'
OUTPUT INSERTED.*

これで、未処理のレコードを定期的にチェックするプロデューサー スレッドをアプリケーションに含めることができます。そのスレッドが作業を完了すると、項目が にプッシュされ、ConcurrentQueueコンシューマ スレッドは作業が利用可能になったときに処理できます。コンシューマ スレッドの数を自分で最適なレベルに設定できます。コンシューマ スレッドが完了するIsProcessing = 0と、PC が更新されたことを示すように設定されます。

于 2012-06-07T22:26:36.170 に答える