[pgsql-jp: 26641] Re: 会員登録の重複

Naofumi Kondoh nkon @ shonan.ne.jp
2002年 7月 9日 (火) 23:58:47 JST


ソフト工房の近藤です。

Yoshitake Shinohara wrote:
> よしたけ@YYNです。
> 
> 
>>WebPageから会員情報を記入、「登録」ボタンを押すと
>>・email重複チェック
>>・会員テーブルinsert(pkeyはserial)
>>という流れで登録処理を行うのですが、何故かたまにemailの重複した
>>会員データが登録されてしまいます。
>>短時間の内に、複数innsertが連続して行われるようです。
>>何故このような重複が発生するか?また、回避策をアドバイスお願いします。
> 
> 
> トランザクションとロックをキーに検索される事をお薦めします。
> 具体的には、
> bigin;
> lock table 会員テーブル EXCLUSIVE MODE;
> select email from 会員テーブル where email = '<new_email>';
> 結果がOKなら
> insert into 会員テーブル (email) values ('<new_email>');
> commit;
> NGなら rollback;


どうしても、email を UNIQUE INDEX にできないならば、
よしたけさんの言われるとおり、LOCK TABLE しかないですね。

LOCK TABLE 表名   IN   EXCLUSIVE MODE ;

ただし、LOCK TABLE を使うと、併行性は悪くなるので、
レスポンスタイムに十分気をつけてください。

また、PostgreSQL の LOCK TABLE は、すでにロックされてい
た場合、そこでブロックされて LOCK が解除(COMMIT/ROLLBACK)
されるまで待ち続けます。LOCK されているか否かを知る方法は
ないはずです。


やはり、
email に UHIQUE INDEX を設定するのが簡単でスマートです。

何らかの理由で、email の重複を認めなければならない場合
があるなら、本処理専用に email を primary key にした
チェック専用の表を作って、重複チェックするなんていう
ことも考えられるかもしれませんが。。。。。
DB設計を見直した方がいいと思います。


(追記)
トランザクション中で、SELECT して重複がないことを確認
してから INSERT しても、その間に別の処理が、同じ KEY
を INSERT することはできます。勘違いしそうなところな
ので注意。

INSERT でなくて UPDATE ならば、他の処理が同時更新したり、
コミット前の値を読めないようにできますが。

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 (株)ソフト工房   近藤直文        Email:  nkon @ shonan.ne.jp
http://www.SOFTKOUBOU.co.jp/      http://www.shonan.ne.jp/~nkon/
2002-07-27(土)14:00-16;30 JPUG 業務アプリ分科会 セミナー/勉強会
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/





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