2012年9月12日水曜日

Groongaのテーブルロック

Groongaのテーブルをロックするときの話。

まぁGroongaはロック意識しないで使えるデータストアですけれども。
特に参照時はロックフリーなのが売りでもある。

でもちゃんとロックするメソッドはあって

Groonga['Programs'].lock do
   programs = Groonga['Programs'].select do |program| program.start <= Time.now end
   # なんたらかんたら
end

みたいに、参照中に他かからのインサートを防ぐことができる。

んが。実際やりたいことって、検索してなかったら追加するみたいなのをアトミックにやりたいのであって、そういうのはGroongaにないみたいな(たぶん、トランザクションないってどこかに書いてあったし)。
例えば、こんなふうにすると、add でロックが必要なのでささって抜けなくなるる。

Groonga['Reserves'].lock do
   reserve = Groonga['Reserves'].has_key?(program._key)
   Groonga['Reserve'].add(program._key, {なんたらかんたら}) unless reserve
end

気にせず上書きすれば良いじゃんて話もあるがそんな乱暴する子に育てられてはいないので、どうしようと考えた結果、ロック専用テーブルを作ることにした…。

Groonga['ReservesLock'].lock do
   reserve = Groonga['Reserves'].has_key?(program._key)
   Groonga['Reserve'].add(program._key, {なんたらかんたら}) unless reserve
end

本当に場当たり的で気が進まない。
他でロックし忘れて add していたり、まちがえて実テーブルロックすると破滅みたいなバグが混入しやすい。
もっとスマートにやる方法があれば教えて欲しい。

0 件のコメント:

コメントを投稿