Prioritized Subscription 時の Q4M の動作


複数のキューの中で、データのあるものを探して取って来る Q4M の便利機能。

mysql> SELECT queue_wait('high_priority_table', 'low_priority_table', 10);

これのこと。


エラーキューとしてウチでは使おうと思っているが、これの動きに若干癖があったのでメモっとく。


まず、この書き方をするときは、タイムアウト指定が必須。

select queue_wait('a', 'b');

こういう書き方をすると、a テーブルの中身しか見てくれない。

select queue_wait('a', 'b', 60);

のようにタイムアウトを必ず指定する。(上の例だと60秒)
ちなみに、これはチュートリアルにも書いてある。


若干??になったのが、
チュートリアルの一番上に書いてある「一番簡単なq4mの使い方」の例 SQL

mysql> SELECT * FROM my_queue WHERE queue_wait('my_queue');

を、Prioritized Subscription の場合どう書けばいいのか?ということ。


結論としては、「この書き方は出来なくなる」のではないかと思った。


奥さんの説明によると、Prioritized Subscription の時は、

select queue_wait('a', 'b', 60);

とやってもらって、a にデータがあれば、1、b にデータがあれば、2 が
返って来るんで、それで取り出すキューを決めてくださいと。


で、その際にもし、データを取ってないキューを見ても問題ない。
例えば、a にも b にもデータが入っていた場合、a からは一件のデータが取得できるが、そのときにもし、b を見たとしても Empty set が返って来るだけですよ、ということだ。


これは実際試してみてもそうだった。


なので、奥さんが想定しているやり方というのは、

select queue_wait('a', 'b', 60);

⇒1が返って来た場合:

select * from a;

⇒2が返って来た場合:

select * from b;


という風に queue_wait() の返却値で from を分ける方法なのだと思う。


ただ、ちょっと思ったのは、奥さんの説明によるとデータの無いキューに対して select をかけても Empty set が返ることは保証されてるそうなんで、

mysql> select * from a union select * from b;

というのもありだなーと。若干無駄な負荷が発生してしまうが、上記のようにすると、どっちかデータのあったほうを返してくれる。うちではプログラマーさんが上記の場合わけコーディングを面倒臭がったんで、こっちのやり方になりそうだw。


追記:

select queue_wait('a', 'b', 60);

において、実際に無いテーブル等を指定すると、NULL が返って来る。これも後から気付いたので、メモっておく。いわゆる実行時例外系ではあるが、呼び出し側は NULL を想定しとく必要はあるだろう。