複数のエージェントがテーブルから顧客を 1 つずつロードするコール センター プログラムを C# で作成しています。複数のエージェントが同じ顧客をロードするのを防ぐために、行がロックされていることを示す新しいフィールドをテーブルに追加しました。行を選択したら、その行を更新し、ロック フィールドをその行を選択したエージェントの ID に設定します。しかし問題は、行を選択してロックしている間です。まだロックされていないため、別のエージェントが同じ行を選択できます。この状況を処理する方法はありますか? データベースは MySQL 5 / InnoDB
質問する
796 次
3 に答える
1
エージェントごとに 1 つのプロファイルのみをロックできると仮定します。
--Check for no lock
UPDATE T SET LockField = 'abc' WHERE ProfileId = 1 AND LockField IS NULL;
--Check to see if we updated anything.
--If not, we can't show this row because someone else has it locked
SELECT ROW_COUNT();
更新を実行する前に、ID を選択する必要があります...
1 つのステートメントで UPDATE を実行する場合は、そうではありません。MySQL 構文に関する私の知識を少し超えていますが、次のようなものです。
--Check for no lock
UPDATE T SET LockField = 'abc' WHERE ProfileId = (
SELECT ProfileId FROM T WHERE LockField IS NULL LIMIT 1
);
--Check to see what we updated
SELECT * FROM T WHERE LockField = 'abc';
非常に簡単に動作します。
もう少し複雑にしたい場合 (または MySQL がサブクエリをサポートしていない場合)、SELECT...FOR UPDATE で更新ロックを使用できます。
START TRANSACTION;
--Put an update lock on the row till the xaction ends
--any other SELECT wanting an update lock will block until we're out of the xaction
SELECT @id = ID FROM T WHERE LockField IS NULL LIMIT 1 FOR UPDATE;
UPDATE T SET LockField = 'abc' WHERE ID = @id;
COMMIT TRANSACTION;
于 2012-05-09T02:21:44.893 に答える
0
チェックアウトしLOCK TABLES
てUNLOCK TABLES
:
http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html
これをマークの回答と組み合わせて使用 できます。
于 2012-05-09T02:29:37.127 に答える
0
あなたが説明しているのはOptimistic Concurrency と Pessimistic Concurrencyです。
于 2012-05-09T02:54:16.857 に答える