PostgreSQLでdeadlock detectedが出るんだけど・続きの続き
追記(2009.12)
結論から言って、LudiaはPostgreSQL8.1はダメです。8.2にしましょう
- -
PostgreSQLのロックモードについていろいろ考えてしまったけれど、そもそもの問題はdead lockだったわけで、とりあえずの回避方法を考えた
ヒントはLudia開発日記さんのところの
プロセス19300
資源211573に対して、ロックレベル低を取得。
資源211573に対して、ロックレベル高を取得。
資源211573に対して、ロックレベル高を解放。
資源211573に対して、ロックレベル低を解放。
プロセス19291
資源211573に対して、ロックレベル低を取得。
資源211573に対して、ロックレベル高を取得。
資源211573に対して、ロックレベル高を解放。
資源211573に対して、ロックレベル低を解放。
この2つのプロセスが走ると、デッドロックが起きる可能性があります。
ちなみに、明示的ロックには、
トランザクション内のオブジェクトに対して獲得した最初のロックが、
そのオブジェクトが必要とする最高位のモードであることを確実に保証すべきです。と書いてあります。
PostgreSQLのロック制御 - Ludia開発日記
INSERTやUPDATEでAccessExclusiveLockになっちゃう理由はよくわからないけど、これって、AccessExclusiveLockになっちゃうなら最初から明示的にでもAccessExclusiveLockにしとけってことだよね
というわけでクエリを
BEGIN;
LOCK TABLE master IN ACCESS EXCLUSIVE MODE;
UPDATE 〜
COMMIT;
ってな具合に変更!
いちいちSELECTがUPDATEを待ってて運用的にアレだけど、dead lockにはならなくなったみたい
ちょっとこれで様子を見る