id name
------------------
1 doraemon
2 nobita
3 jyaian
4 doraemon
idは、連番でシーケンスで採番されます。
nameは、名前です。ここは、既に同じ名前が存在したら登録NGとしたいです。
ただ、既にテーブルにはdoraemonが重複して登録されています。
これはOKで、Webからの登録の場合、重複NGとしたいです。
テーブルのnameが完全にユニークであれば、ユニーク制約をいれれば
重複して登録できないようにできますが、
上記のとおり、すでに名前があるのでユニーク制約をいれられません。
この状況で、複数人が、同時に、suneoと入力したときに、
エラーとしたいのですが、なにか方法ありますでしょうか。
プログラムで行う場合とデータベースの排他制御機能で行う方法が考えられます。
データベースが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にすることで実現可能です(他のアプリケーション等からの
アクセスがない場合のみ)