4

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

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

私の考えは、プロセスが既に処理中であることを示す行でキュー テーブルを拡張することです。処理アプリケーションは、最初にその識別子を使用してテーブルを更新し、次に更新されたレコードを要求します。

だから、このようなもの:

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

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

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

最初:これはこの形で機能しますか?

第二に、それが機能している場合、それは効果的ですか? そのようなディストリビューションを作成するための他のアイデアはありますか?

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

4

4 に答える 4

6

これは機能しますが、複数のプロセスが同じデータの読み取り/更新を試行するブロックまたはデッドロックに遭遇する可能性があります。こちら で説明されているように、この種のものがブロックやデッドロックなしで実行されることを保証するために、いくつかの興味深いロックセマンティクスを使用するシステムの 1 つに対して、まさにこれを行うための手順を書きました。

于 2008-10-30T09:05:27.897 に答える
1

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

update mytable with (rowlock) set x=y where a=b
于 2008-10-30T09:46:02.387 に答える
1

このアプローチの最大の問題は、テーブルへの「更新」の数を増やすことです。たった 1 つのプロセスでデータを消費 (更新 + 削除) し、他のプロセスでテーブルにデータを挿入してみてください。約 100 万件のレコードでデータが崩れ始めることがわかります。

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

于 2009-02-25T04:15:57.887 に答える
1

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

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

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

そうは言っても、私はDBAではないので、これ以上の専門家の回答にも興味があります

于 2008-10-30T08:54:14.910 に答える