21

実行するタスクの MySQL テーブルがあり、各行には単一のタスクのパラメーターがあります。
ループ内でタスクを実行する多くのワーカー アプリ (異なるマシン上にある可能性があります) があります。
アプリは、MySQL のネイティブ C API を使用してデータベースにアクセスします。

タスクを所有するために、アプリは次のようなことを行います。

  • グローバルに一意の ID を生成します (簡単にするために、数字であるとしましょう)

  • UPDATE tasks
    SET guid = %d
    WHERE guid = 0 LIMIT 1

  • SELECT params
    FROM tasks
    WHERE guid = %d

  • 最後のクエリが行を返す場合、それを所有し、実行するパラメーターがあります

サーバーへの単一の呼び出しで同じ効果 (つまり、行を「所有」してそのパラメーターを取得する) を達成する方法はありますか?

4

6 に答える 6

10

このようにしてみてください

UPDATE `lastid` SET `idnum` =  (SELECT `id` FROM `history` ORDER BY `id` DESC LIMIT 1);

上記のコードは私のために働いた

于 2012-10-08T09:03:26.840 に答える
7

それを行うプロシージャを作成できます。

CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200))
BEGIN

  DECLARE task_id INT;

  SELECT id, out_params
  INTO task_id, out_params
  FROM tasks
  WHERE guid = 0
  LIMIT 1
  FOR UPDATE;

  UPDATE task
  SET guid = in_guid
  WHERE id = task_id;

END;

BEGIN TRANSACTION;

CALL prc_get_task(@guid, @params);

COMMIT;
于 2009-02-18T20:43:38.990 に答える
1

単一のクエリを探している場合、それは起こりません。UPDATE 関数は、更新されたアイテムの数だけを具体的に返します。同様に、SELECT 関数はテーブルを変更せず、値を返すだけです。

プロシージャを使用すると、実際にそれが単一の関数に変わり、ロックが懸念される場合に便利です。ネットワーク トラフィックが最大の懸念事項である場合 (つまり、クエリが多すぎる場合) は、次の手順を使用してください。サーバーの過負荷が懸念される場合 (つまり、DB が過剰に動作している場合)、プロシージャの余分なオーバーヘッドが事態を悪化させる可能性があります。

于 2009-02-18T21:05:29.123 に答える
0
UPDATE tasks
SET guid = %d, params = @params := params
WHERE guid = 0 LIMIT 1;

値が効果的に変更されたかどうかに応じて、1 または 0 が返されます。

SELECT @params AS params;

これは、接続から変数を選択するだけです。

から:ここ

于 2014-08-07T11:37:52.830 に答える
0

単一の呼び出し部分についてはわかりませんが、あなたが説明しているのはロックです。ロックは、リレーショナル データベースの重要な要素です。

行をロックし、それを読み取り、MySQL で更新する詳細はわかりませんが、mysql ロックのドキュメントを少し読むだけで、あらゆる種類のロックベースの操作を実行できます。

postgres のロックのドキュメントには、何をしたいのかを正確に説明する素晴らしい例があります: テーブルをロックし、テーブルを読み取り、テーブルを変更します。

于 2009-02-18T20:35:30.240 に答える