• ベストアンサー

二重登録エラー時の再登録

javaで登録処理を行ないますが、以下のようなことは 可能なのでしょうか? 環境 DB postgress java1.4.2 やりたいこと TBL-A のキーは1から連番の項目Aです。 最大のAを取得し+1した値で登録します。 2人以上が同時に実行した場合二重登録違反が発生する 可能性がありますので二重登録違反が発生すれば再度 最大のAを取得して登録をやり直したい。 この処理がその他のことで長い時間が掛かりますので 排他をかけたくないと思っています。 ご存知であればご教授お願い致します。 (出来るか出来ないかだけでも教えてください)

  • hammy
  • お礼率84% (32/38)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

>この処理がその他のことで長い時間が掛かりますので >排他をかけたくないと思っています 最大値を拾って、+1して、insertするのですよね? それを排他制御なしで行えば、データとインデクス間などでDBに不整合が起こったりしますよ? 一時的に占有してしまうなら、まだ分かりますが。 ロールバック等が発生して、途中の番号に抜けが生じることは許されないのでしょうか?もし途中に欠番が生じてもいいので、順次、ユニークな番号でいいなら、PostgreSQLには、連番型(serialまたはsequence)があります。 http://www.postgresql.jp/document/pg823doc/html/datatype-numeric.html#DATATYPE-SERIAL

参考URL:
http://www.postgresql.jp/document/pg823doc/html/datatype-numeric.html#DATATYPE-SERIAL

その他の回答 (1)

  • moritan2
  • ベストアンサー率25% (168/670)
回答No.2

この手の処理は普通は seqence を使うと思います。sequence はロックしなくても同じ値は絶対に取得されることが無いことが保証されています。ロールバックが発生した場合に、値が欠番になってしまうことがあるのですが、これはしかたがないでしょう。

関連するQ&A

  • ORA-1403

    質問するカテゴリが間違っていたら申し訳ありません。 oracleを使用しWEBアプリを開発しています。 DB連携を行っていて、 WEB--DB--DB処理という形になっています。 言語はWEB側が java1.5(struts1.2)コンパイルは1.4準拠 DB処理が Cです。(PRO C?) WEB側で値を格納し、DB側で入力値によって処理を 行い結果を格納するのですが、たまにORA-1403のエラーが発生し 正しく処理ができません。 例 tbl_master A001(PK), A002   , A003 ID    , linkcode , 結果 tbl_link001 A001(PK), A002  , A003 ID    , 値1  , 値2 WEB側でDB格納する際にDB接続からリリースまでのメソッドに synchronizedをかけていますが、これが影響しているのでしょうか? DBのロックではないので問題は無いとは思っているのですが・・・。 ご存知の方がいらっしゃいましたらご教授いただけますでしょうか。 お願いします。

  • 登録する行の変更

    以下のコードで「入力」シートのデータから「DB]シートに登録するんです。「DB」シートの一行目A1は題名ですが新しいデータに入ってくるとどんどん題名は下の行に下がっていく。 題名は固定し、新しいデータはA2から入ってくるようにしたいですがどこに変更すればいいかわからなくて困っています。(ExcelのVBAはまったくわかりません) よろしくお願いします。 Excel 2007 Sub 登録_Click() 'On Error GoTo Err_登録 Dim n As Integer '入力明細の数 Dim x As Long 'DBの検索範囲の最終行 Dim rng As Range '検索したセル Dim z As Long 'DBのデータの最終行 Dim tbl As Worksheet '[DB]シート Dim key As String '検索キー Dim from_key As Long '更新範囲(自) Dim to_key As Long '更新範囲(至) '警告メッセージ非表示 Application.ScreenUpdating = False Worksheets("入力").Activate Set tbl = Sheets("DB") z = tbl.Range("A1").CurrentRegion.Rows.Count Check_登録: key = Range("B2").Value If key = "" Then MsgBox "発注番号が未入力です。" Exit Sub End If '[発注番号]でソート tbl.Range("A1").Sort Key1:=tbl.Range("A1"), Header:=xlGuess '存在チェック x = tbl.Range("A1").End(xlDown).Row With tbl.Range("A1:A" & x) Set rng = .Find(key, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows) If Not rng Is Nothing Then MsgBox "既存の番号が存在します。" Exit Sub End If End With '明細行有無チェック n = WorksheetFunction.CountIf(Range("M46:M65"), "*") If n = 0 Then MsgBox "明細行がありません。" Exit Sub End If Add_登録: '空白行を省く Selection.AutoFilter Field:=14, Criteria1:="<>" 'コピー&貼り付け Range("A47:U66").Copy tbl.Range("A" & z + 1).PasteSpecial Paste:=xlPasteValues '[発注番号]でソート tbl.Range("A1").Sort Key1:=tbl.Range("A1"), Header:=xlGuess 'コピーモード解除 Application.CutCopyMode = False '空白行を省くを解除 Selection.AutoFilter Field:=14 'ブック保存 'ActiveWorkbook.Save '画面クリア Call 画面クリア '警告メッセージ表示 Application.ScreenUpdating = True Exit_登録: MsgBox "登録しました。" Exit Sub Err_登録: MsgBox "エラーが発生しました

  • SESSIONの取得タイミングについて

    現在簡単な会員登録のサイトを作っているのですが フォームに入力してもらった値を同じ画面でDBに登録するのではなく、 確認画面を新しく起こしてそこで登録ボタンを押せばDBに書き込むようにしたいのですが上手くいきません。 処理の順番は 1.フォームの確認ボタンを押されると値をSESSIONに登録(PHP)  ↓ 2.確認ボタンで新しいWindowをJavaで起こします  ↓ 3.確認画面でSESSIONの値を確認  ↓ 4.SESSIONの値をDBに登録 としたいのですが どうも2.の処理が1.よりも先に入って確認画面にはSESSIONの値が入っていません。 親WindowではSESSIONの値は入っているのですが。 確認ボタンに値の取得と新しいWindowを開くJavaと2つの機能を持たしていることが原因だろうとは思うのですが、 Windowを開くタイミングを遅らせる等の処理でうまく回す方法はありませんでしょうか? (Javaを使ったのはWindowサイズを変更したかったからです。) ご存知の方おられましたらご教授願えないでしょうか。 よろしくお願いします。 環境 レンタルサーバーにてPHP4+MySQL4

    • 締切済み
    • PHP
  • PerlからDB接続し、データ登録時のエラー処理について

    PerlからDB接続し、データ登録時のエラー処理について DBにデータを登録するときにエラー処理を加えたいと思っていますが、 色んなサイトを参考にさせて頂いて、下記のようにしてみたのですが うまくできません。 $sth = $db->prepare(" INSERT INTO DBNAME (hinmei,su,tani,tuikabi) VALUES($hinmei,$su,$tani,$hiduke) "); if(!$sth->execute){  print "接続エラー";  exit; } または、 $sth = $db->prepare(" INSERT INTO DBNAME (hinmei,su,tani,tuikabi) VALUES($hinmei,$su,$tani,$hiduke) "); $sth->execute or &error('DBに登録出来ません'); 両方とも登録出来なければエラーメッセージを出すように してみたのですが、キー項目が同じものを登録しようとすると $sth->execute この部分でとまってしまうらしく、次の処理に行きません。 もちろん、キー項目が同じでなければDBに登録出来ます。 どうすればエラー処理の設定ができるでしょうか。 教えてください。 お願いします。

    • ベストアンサー
    • Perl
  • DB INSERT 時の排他制御について

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

  • 一度のSQL発行で結果を得るにはどのようなSQLにすれば良いでしょうか

    一度のSQL発行で結果を得るにはどのようなSQLにすれば良いでしょうか? データベースはOracleです。 二つの履歴テーブルがあり、それぞれ主キーは「連番」です。 連番が最も大きい値の社員番号と社員名を取得しようとしています。 (他にもカラムはありますが質問では省略しています。) 連番は別に管理テーブルがあり、そちらから採番しているので 二つのテーブルで連番が重複することはありません。 【RIREKI_TBL_A】 連番 NUMBER(10) 社員番号 VARCHAR(7) 社員名 NVARCHAR(20) 【RIREKI_TBL_B】 連番 NUMBER(10) 社員番号 VARCHAR(7) 社員名 NVARCHAR(20)

  • 【access】型の異なるTBLへの登録方法

    access2010を使用しツールを作成しております。 以下の処理順でTBLに値を登録したいです。 (1) テキストファイル(.txt)を一時格納TBLに登録 (2) 一時格納TBLの値を正規TBLに登録 一時格納TBLの型は仕様上、全てテキスト型を指定。 正規TBLの型は正しいものを指定したいのですが、insertやupdateでは上手くいきません。 ※この点は理解して上記仕様にしております 処理の流れとして以下を考えていますが、 他に良い手段がある場合はご教示頂けないでしょうか。 (1) テキストファイル(.txt)を一時格納TBLに登録 [一時格納TBLは全てテキスト型] (2) 一時格納TBLの値を正規TBLに登録 [正規TBLは全てテキスト型] (3) ALTER TABLEで必要に応じ正規TBLの型を修正する   ex)テキスト型→日付型、テキスト型→長整数型 ※ このやり方だと、正規TBLの型を書き直してしまうため都度型指定をやり直さなければならず現実的な処理ではない。 またALTER TABLEの本来の使い方ではないと思っている。 詳しい方、良い手段をご教示ください。

  • DB参照&登録処理、どっちが高速?

    30日分の売り上げを登録するシステムをつくっています。 登録先はDBで、日付を主キーとして1レコードずつ増えていく感じですが、既に登録があるものについてはレコード有無の判断をして上書きにする必要があります。 処理を考えたところ、2パターンのどちらが高速か負荷が少ないのかで迷っており、助言をいただきたいと思い投稿しました。 <1> (1)DB接続 (2)既に登録されている日付を把握するため、レコードから日付を全て取得(select all) (3)登録しようとしている1日目の日付とDBから取得した日付を全て照合し、同一があれば上書き(update)、なければ登録(insert)で処理をする。 (これを30日分繰り返す) (4)DB切断 <2> (1)DB接続 (2)登録しようとしている1日目の日付をキーにDBに同一日での登録がないか参照(select)し、同一があれば上書き(update)、なければ登録(insert)で処理をする。 (これを30日分繰り返す) (3)DB切断 <1>はDB参照が一度で終わるので高速かなと思うのですが、参照結果を一度格納し、再度1つづつを比較としてひっぱってくるためあまり効率が良くないのかと悩んでいます。 アドバイスお願いいたします。

    • ベストアンサー
    • PHP
  • selectの内容によって、登録するカラムを変えたい

    selectの内容によって、登録するカラムを変えたい selectであるテーブルからある値Aをとってきます。 値Aが1の時は別テーブルの金額1に登録、2の時は金額2に登録、3の時は金額3に登録 という処理を行いたいです。 同一レコードに対して複数の金額がある事があります。 テーブル1(取得テーブル) ------------------ キー 値A 金額 1   1  500 1   3  300 2   3  200 ------------------ テーブル2(登録テーブル) ------------------ キー 金額1 金額2 金額3 1   500  0  300 2    0  0  200 ------------------ いま、 insert into テーブル2 SELECT 項目 from テーブル1 というように1つのSQLで、登録、削除をしようとしていますが 可能でしょうか?。方法がよく分かりません。

  • オラクルで更新するまで、排他使用中にする

    オラクルで、 受注テーブルと連番ファイルがあります。 端末が100台位あり、どの端末でも受注を入力します。 受注テーブルのキーは連番で、連番ファイルから取得して、1加算した値を受注ファイルの連番にセットし、連番ファイルの値を更新します。 このような場合、同時に受注を行われた場合、 端末(1)が連番ファイルを取得し、更新する間に、 端末(2)が連番ファイルを取得すると、 同じ連番で受注ファイルを作成してしまいます。 SELECT 連番 FROM 連番ファイル UPDATE 連番ファイル SET 連番=XXXXX 回避策として、データをつかんでいるときに、排他制御などがかけれると聞いたことがあるのですが、どうやって書けばよいのでしょうか?