- 2006-10-03 (火) 18:42
- Web+DB
PHP4+PostgreSQL7.4での開発中にトランザクションが終了しない現象が発生しました。アプリケーションのログを見てみても[begin]は発行されているのに[rollback/commit]が発行されていませんでした。
結局これ自体はPHP側の問題でPostgreSQLは無関係だったのですが、問題の処理を調べている際に複数回処理を実行するとロック待ちのような状態になりました。この処理ではアプリケーションから明示的にロックを行っていなかったので不思議に思い、DBのログを見てみると以下のようなログを発見。
LOG: statement: SELECT 1 FROM ONLY "public"."t_category_m" x WHERE "category_id" = $1 FOR UPDATE OF x
アプリケーションで発行しているSQLではないのでgoogleに聞いて以下のサイトを見つけました。
行ロックをかける理由は,t2が参照している行が削除されるようなことがあると困るからである。そうなると,t2がt1を参照しているという参照整合性制約が崩れてしまうから,それを防ぐためにロックをかけるのはやむをえない措置と言える。
【PostgreSQLウォッチ】第20回 PostgreSQL 8.1ベータ・テスト開始,新機能ロールと共有行ロック:ITpro (2006-10-03)
外部キーを含む行をINSERTすると参照テーブルの関連行をロックしてしまうとの事です。まあ考えてみると当たり前なのですが、特に意識していなかったので「?」になりました。
普段は問題無いんでしょうが、これ意識しておかないと処理待ちやデッドロックが発生したりとまずい事になりそうです。
ちなみに8.1からは記事にあるとおり共有ロックにてこの問題は回避されているそうです。
- Newer: display_errorsはoffに
- Older: PHPで1から100を表示
トラックバック:0
- このエントリーのトラックバックURL
- /blog/2006/10/pgsql_for_update_x.html/trackback
- Listed below are links to weblogs that reference
- PostgreSQL 外部キーロック from Shin x blog