[pgsql-jp: 40591] Re: グループ毎に自動採番したいのですが

Itagaki Takahiro itagaki.takahiro @ gmail.com
2010年 12月 5日 (日) 16:54:13 JST


2010/12/5 yukihito miso <mail @ rishiri.info>:
> -- IF NOT FOUND
> --   FIXME: u_idごとの最初の行の時には別のロックが要る?
> -- END IF;
> は、どうしてこの処理"別のロック"が必要になるのでしょうか?

ある u_id に対して行を追加する際には
>>  PERFORM 1 FROM users WHERE u_id = 1 AND s_id = 1 FOR UPDATE;
として毎回 (u_id, s_id) = (<値>, 1) を行ロックすることで、
平行して追加があった際に同じ値の s_id を追加することを防いでいます。

ところが、初回、つまり s_id = 1 を追加する際には、まだ行ロック
対象の業が無いので、排他制御ができません。これがコメントの意図です。

ただ、初回の追加時は u_id をシーケンスから生成するはずなので、
並行で (同じ u_id, s_id = 1) を挿入することは無い気がします。
実際には、気にしなくても良いケースが多いと思われます。
(元メールの「アプリ的にも特別扱い」は、このことです。)


>> INSERT INTO users (u_id, s_id) VALUES (<値>, DEFAULT);
> というののINSERT文ですが
> DEFAULTにmax(s_id)+1の値が入るという動作でいいのでしょうか?

「どんな値を指定しても、トリガで強制的に上書きされる」イメージです。
DEFAULTでなくても構いませんが、0 等の特定の値を与えるよりは
しっくりくる気がしたので、DEFAULTにしておきました。

-- 
Itagaki Takahiro


pgsql-jp メーリングリストの案内