• 締切済み

DB INSERT 時の排他制御について

初めて投稿するものです。 Java で DB 挿入処理 (会員登録) で悩んでおります。 DB はPostgreSQL8です。 挿入しようとしている会員テーブルは以下のようなレイアウトです。 会員テーブル  ・会員ID 主キー  ・ログインID NOT NULL(*)  ・メールアドレス NOT NULL(*)  ・会員名  ・... ※(*)にはユニーク制約を付けています。 会員IDはPostgreSQLのシーケンスで採番するため、 排他ロックは不要であると思っております。 ですが、ログインIDとメールアドレスは ユニークであるため、排他制御して重複 チェックしなければならないと思っています。 ユニーク制約を張っているため、例外が 発生して判定するというアイデアもあるとは 思いますが、例外で重複判定するのは できれば避けたいと思っております。 例外以外で安全に重複チェックする 場合、どのように排他制御するべきでしょうか? そもそも、排他制御せずに重複チェックを 安全にする方法はあるのでしょうか? ユーザーが多いサイトの場合、テーブルを ロックすると遅くなるような気がします。 ご教授よろしくお願いいたします。

みんなの回答

  • notnot
  • ベストアンサー率47% (4843/10252)
回答No.1

PostgreSQLをよく知らないので、言葉が多少違うかもしれません。 未使用のとあるログインIDを使いたいという人が二人同時に登録作業するケースを想定すると、更新排他は必須です。ただ、会員テーブル全体を更新排他する必要はなく、登録制御用のレコード(例えば主キー=00000)を更新排他すれば、登録処理が同時に動くことはないので十分です。 (1) 一般のリクエスト 参照排他で会員テーブルをアクセスする (2) 登録リクエスト 00000レコードに更新排他を掛け、会員テーブルを参照排他で重複がないかチェックし、無ければインサートする。 もしかしたら、登録制御用のレコード(上記00000)は別に1レコードだけの専用テーブルを作った方が良いのかもしれません。

cammy22
質問者

お礼

ご回答本当にありがとうございました。 登録制御用のテーブルというのは良いアイデアかもしれませんね! これを使用すれば登録以外の処理がロックされることもないですね。 ありがとうございます。 本当に参考になりました。

関連するQ&A

  • 排他制御に関して

    こんばんは。お世話になっております。 これまで、質問のタイトルにある「排他制御」というものが「同時アクセスでの不具合を避けるための・・」といった程度の知識しかないまま、DB(MySQL)を利用して会員制のサイトを作っているのですが、全体を見直すべく、いざこの排他制御というものを取り入れようとしてみたところ、手持ちの書籍やこれまで見たサイトでは、ファイルをロック・・・などと言った感じで、DBとの関わりがイメージ出来ず、会員の登録情報の変更ページなどの入力フォームをはじめ、ログインページやDBを用いた検索ページにおいての活用は、どのような手順になるのでしょうか? 些か抽象的な質問になっておりますが、取り掛かりがつかめず、例えばログインページを例にとり、IDとパスワードを入力・DBに問合せ、といった流れでは、どのような手順になるかの全体像だけでもアドバイスいただければと、投函させて頂きました。 お忙しい中恐縮ですが、アドバイスなど頂戴できれば幸いです。宜しくお願い申し上げます。

    • ベストアンサー
    • PHP
  • ACCESS97での排他制御について

    今、仕事の都合でACCESS97を利用して、排他制御のある システムを作成しようと試みているのですが、なかなか上手くいきません。 DB、APをネットワーク上に置き、共有するテーブルを、DB→APに リンクをはっている状態です。 様々なIT上で調べたのですが、どれもACCESS97で排他制御は不可能 といった内容のものしかありません。。 どうしても、不可能なのでしょうか?もし、何かご存知でしたら、教えて頂け ないでしょうか??

  • Access2003での排他制御

    Access2003での排他制御 顧客管理をAccess2003で行っています。 新規で登録するときに顧客IDの重複チェックを[顧客ID_LostFocus]内で DCountを使って行っています。 [cmd登録_Click]で Set db = CurrentDb Set rst = db.OpenRecordset("顧客情報") With rst .AddNew ![顧客id] = me.txt顧客ID.value ![顧客住所] = me.txt顧客住所.value ![顧客TEL] = me.txt顧客TEL.value ・ ・ ・ .Update End With 以上の処理を行っています。 (1)Aさんが新規登録で顧客IDを入力 (2)重複されていないので顧客名や住所の入力をおこなう。 (3)Bさんが同じ顧客IDで新規登録 このケースの場合、 Aさんはまだ登録処理が済んでいない(登録ボタンを押していないためテーブルに反映されていない) ので(3)ではBさんの顧客IDは重複されていません。 Aさんが入力中の顧客IDをBさんが入力した時に「他のユーザーが使用しています」みたいな メッセージを表示するにはどのようにしたらよろしいでしょうか?? 文章が上手く書けなくてもうしわけありません、 何卒宜しくお願いいたします。

  • Accessでの排他制御

    アクセスの排他制御に関して質問です。 ネットワーク上のサーバーにアクセスのMDBを置いて、複数の人が更新目的で開く場合、排他制御はどうなるのでしょうか? テーブル単位で、ロックが掛かるのでしょうか? もしそうであれば、複数の人が同時に使えないのですが、回避策はありませんでしょうか?

  • 同一レコード更新時の排他制御

    Oracle9iです。 C/S開発で、VB.NETで画面を開発します。 DBの更新は、画面よりストアドプロシージャを使って行います。 複数ユーザが同一レコードを同時に参照し、同一レコードに対して更新された場合、参照時の更新日時と異なる場合はエラーとするよう設計されています。(つまり、後更新はエラー) この排他チェックロジックを画面側で実装しようとしておりますが、この排他チェックロジックを画面側で実装せずに、Oracleよりエラーレコードを受け取ることによる排他制御を行うことはできないでしょうか? ご教授のほどよろしくお願いいたします。 また、参考サイトあれば、その紹介だけでも助かります。

  • Oracleの排他制御について教えてください

    質問内容は結論から言うと、 INSERT文の時の排他制御について 知りたい。 以下の私の認識を踏まえた上で、 INSERT文の排他制御について 質問させてください。 なお、私の認識に誤りがあれば 指摘してください。 ### 私の認識 start ###### 1)Oracle では、select文の時に for updateを 書かなければ、なんのロックもかからず、 読み取り専用リソースへのアクセスで ない限り、 ダーティーリードの可能性がある。 2) select文で for update を指定した場合は 該当行について 共有ロックがかかる。 行単位の共有ロックがかかる。 その際、 他のトランザクションが for updateつきで selectしてきても、 共有ロック同士なので、 互い排他制御しない。 (3) update 文の場合は 該当行について、 占有ロックがかかる 行単位の占有ロックがかかる。 (4) INSERT文の時には、 ロックをかけようにも INSERT前の段階では、 ロック対象行は存在しない。 複数のトランザクションが INSERTした行のPK の値が偶然同じであった場合 ロストアップデートの危険があるので 私の創造では、INSERT文の時は テーブル全体をロックしないと、 うまくいかないように思えます。 (5) update, insert文については、 Oracleでは、自動的に該当行について 占有ロックを行う。 なお、INSERT文については、 下記の質問事項における疑問点 が解消されていないため、 行単位なのかどうか、私の中では 自身がもてないのが現状です。 ### 私の認識 end ###### ### 主な質問内容 start ### 私の認識の(4)を踏まえた上で INSERT文の時のはいた制御 の範囲や挙動について、 教えてください。 ### 主な質問内容 end ### 以上です。

  • DB2 「既存カラムへのnot null制約の付与・削除方法について」

    DB2有識者の方々へ マニュアルをみたのですが、alter tableでは駄目なのでしょうか? すみません。よろしくお願い致します。 <質問1> 既存カラムへnot null制約を付与したいのですが、コマンドを教えてください <質問2> 既存カラムについた、not null制約を削除したいのですが、コマンドを教えてください よろしくお願い致します。

  • 別のDB(Table)からの複数行のINSERT

    Wordpressにあるusermetaというテーブルに、 別のDBのテーブルからデータをINSERTしたいのですが、 #1241 - Operand should contain 1 column(s) というエラーが表示されてうまくいきませんでした。 具体的なSQL文は、 insert into ***_usermeta (umeta_id,user_id,meta_key,meta_value) select (null,tableBid,'first_name',''), (null,tableBid,'last_name',''), (null,tableBid,'nickname',tableBname), (null,tableBid,'***_capabilities','a:1:{s:10:\"subscriber\";b:1;}'), (null,tableBid,'***_user_level','0') from dbB.tableB where tableBname<> 'Admin' dbBのtableB にあるAdmin行以外を対象としています。 実際にはもう少しデータが多いのですが、select (null,uid,'first_name','') from ・・・ だけにしても同じエラーが出ましたので、構文の書き方が間違っていると感じています。 (別のDBではなく、同じDBの別のTableからのINSERTでも同じエラーが表示されました) 上記のようなケースの場合、どのようにSQL文を書けばよいのでしょうか? お分かりになられる方がいらっしゃいましたら、ご教示頂けますと幸いです。 宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • PostgreSQLの「not null」制約の追加

    こんにちは。いつもお世話になります。 PostgreSQLのversion7.2.8で、「not null」制約の追加、削除の方法をおたずねします。よろしくお願いします。 ALTER TABLE テーブル名 ALTER COLUMN カラム名 SET NOT NULL; で試したところ、syntaxエラー(構文エラー)で失敗。 ALTER TABLE テーブル名 ALTER COLUMN カラム名 DROP NOT NULL; で試してみても、同じくsyntaxエラーです。 version7.2.8が原因でしょうか? また、version7.2.8でも「not null」制約の追加、削除が できる他の方法はありますでしょうか? テーブルを作り直さずに、 既存のテーブルのカラムへの制約の追加、削除をしようとしています。 よろしくお願いします。

  • データベース22年度 午後I 問2 設問2

    ”会員”テーブルの項目は、NULL不可となることが静的に決まらないので、列ごとにNOT NULL制約を定義できない。そこでNULL不可であることを動的に管理する”項目チェック”テーブルを図のように定義した。・・・ というNULL不可を動的に管理する”項目チェック”テーブルの空欄埋め問題で、解答は以下の通りでした。 項目チェック(一連番号,会員列名称,会員区分,職業区分) 一連番号が主キー しかしながら一連番号がどうして必要なのか分かりません。 たとえ新たな職業区分を追加したとしても{会員列名称,会員区分,職業区分}を主キーにしておけばまかなえると思うのですが。 一連番号がサロゲートキーにしか思えないのですが、どなたか解説お願いいたします。