3

MySQL を使用してキューを作成しようとしています (わかっていますが、残念です!)。私が設定した方法は、キュー アイテムに受信者 ID を設定するために更新が行われることです。更新が行われた後、更新されたアイテムを受信者 ID で選択します。

私が直面している問題は、更新のクエリを実行してから選択を実行すると、選択クエリが結果セットではなく true を返すことです。これは、大量のリクエストが行われたときに発生するようです。

なぜこれが起こっているのか誰にも分かりますか?

前もって感謝します。

スキーマ:

CREATE TABLE `Queue` (
  `id` char(11) NOT NULL DEFAULT '',
  `status` varchar(20) NOT NULL DEFAULT '',
  `createdAt` datetime DEFAULT NULL,
  `receiverId` char(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

デキュー:

update `'.self::getTableName().'`
set
    `status` = 'queued',
    `receiverId` = '%s'
where
    `status` = 'queued'
    and `receiverId` is null
order by id
limit 1;

select
    *
from 
    `'.self::getTableName().'`
where
    `receiverId` = \'%s\'
order by id
desc limit 1
4

1 に答える 1

1

これは、ある種の競合状態のように聞こえます。MyISAMを使用しているため、更新が延期される可能性があります(特に、そのテーブルに大量のトラフィックがある場合)。

true戻り値は、selectクエリが正しく完了したが、結果セットが空(行なし)であることを示しています。それが発生したときのロジックが、たとえば50ミリ秒待ってから再試行することである場合、問題が正しく機能していることがわかる場合があります。

編集:UPDATEを実行する前から、最後のSELECTを実行するまで、テーブルのロックを試みることができます。ただし、それによってアプリの他の部分のパフォーマンスが低下する可能性があります。最善の方法は、競合状態に直面してもアプリを堅牢にすることです。

于 2012-08-31T16:28:53.117 に答える