質問

MSSQL 2005のキューとしてデータベーステーブルを使用する小さなシステムがあります。複数のアプリケーションがこのテーブルに書き込みを行い、1つのアプリケーションがFIFO方式で読み取りと処理を行っています。

複数の処理アプリケーションを実行できる分散システムを作成できるようにするには、もう少し高度にする必要があります。その結果、2〜10個の処理アプリケーションを実行でき、作業中に相互に干渉することはありません。

私の考えは、プロセスがすでに作業していることを示す行でキューテーブルを拡張することです。処理アプリケーションは、最初にテーブルをidetifyerで更新してから、更新されたレコードを要求します。

このように:

start transaction
update top(10) queue set processing = 'myid' where processing is null
select * from processing where processing = 'myid'
end transaction

処理後、テーブルの処理列を「完了」などの何かに設定します。

このアプローチについて3つの質問があります。

最初:これはこのフォームで機能しますか?

2番目:動作している場合、効果的ですか?このようなディストリビューションを作成する他のアイデアはありますか?

3番目:MSSQLではロックは行ベースですが、一定量の行がロックされると、ロックはテーブル全体に拡張されます。したがって、最初のアプリケーションがトランザクションを解放しない限り、2番目のアプリケーションはアクセスできません。テーブル全体をロックせず、行ロックのみを作成するために、選択範囲(トップx)をどれだけ大きくできますか?

役に立ちましたか?

解決

これは機能しますが、複数のプロセスが同じデータを読み取り/更新しようとするブロッキングまたはデッドロックが発生する可能性があります。興味深いロックセマンティクスを使用して、このタイプのことをブロックまたはデッドロックなしで実行することを保証するシステムの1つに対して、これを正確に行う手順を作成しました。ここで説明

他のヒント

このアプローチは私には合理的で、過去に使用したものに似ています-成功しました。

また、更新/選択操作が行われている間のみ行/テーブルがロックされるため、行対テーブルの質問は本当に重要な考慮事項であるとは思いません。

アプリの処理オーバーヘッドが無視できるほど低くない限り、「トップ」を維持します。値が低い-おそらく1だけです。もちろん、それはアプリの詳細に完全に依存します。

すべてを言って、私はDBAではないので、専門家の回答にも興味があります

ロックに関する質問について。ロックヒントを使用して、強制的に行のみをロックすることができます

update mytable with (rowlock) set x=y where a=b

このアプローチの最大の問題は、テーブルの「更新」の数を増やすことです。 1つのプロセスのみを使用して(更新+削除)、テーブルにデータを挿入する他のプロセスでこれを試してみると、約100万件のレコードで崩れ始めます。

DBのコンシューマを1つ用意し、メッセージキューを使用して処理データを他のコンシューマに配信します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top