会員登録のWebフォームで、以下のOracleのテーブルに登録する状況についてのご質問です。

id name
------------------
1 doraemon
2 nobita
3 jyaian
4 doraemon

idは、連番でシーケンスで採番されます。
nameは、名前です。ここは、既に同じ名前が存在したら登録NGとしたいです。

ただ、既にテーブルにはdoraemonが重複して登録されています。
これはOKで、Webからの登録の場合、重複NGとしたいです。

テーブルのnameが完全にユニークであれば、ユニーク制約をいれれば
重複して登録できないようにできますが、
上記のとおり、すでに名前があるのでユニーク制約をいれられません。

この状況で、複数人が、同時に、suneoと入力したときに、
エラーとしたいのですが、なにか方法ありますでしょうか。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2014/10/11 02:28:32
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:cno No.1

回答回数124ベストアンサー獲得回数12

ポイント100pt

プログラムで行う場合とデータベースの排他制御機能で行う方法が考えられます。
データベースがOracleとのことですので、Oracleの場合の例を記載させていただきます。

まず、手順を考えると
1)ユーザが指定したnameがすでに登録されているかSELECTで検索
  SELECT count(name) from table where name='suneo'
2)1)の結果、まだ登録されていなければINSERTで登録
  INSERT into table values(val,'suneo')
となるかと思います。

この1)と2)の操作の間に他のアクセスを禁止すれば良いため、
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;で事前に排他制御を設定
1),2)を発行(1)の結果登録済みの場合はROLLBACK;でトランザクションを
終了しないとデッドロックが発生する可能性があります)
COMMIT;コミットしトランザクション終了
となります。

排他制御については
http://www.oracle.com/technetwork/jp/database/articles/tsushima/tsm18-1610822-ja.html
が参考になるかと思います。

Javaなどのクラスベース言語の場合、1)2)を行うクラスをSingletonとし、
メソッドをsyncronizedにすることで実現可能です(他のアプリケーション等からの
アクセスがない場合のみ)

id:yayayai

ありがとうございます!

2014/10/11 02:28:16

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません