• 締切済み

排他制御の仕方

X_DBから条件取得し、Y_DBへデータを移し変える処理を画面PGで行っています。 (移し終わると、該当のレコードはX_DBから削除) この時、複数端末で同時に処理されると、X_DBの対象レコードが重複して選択されるため、排他処理を行いたいのですが、ORCLEでどの様な記述をしたらよいのでしょうか?

みんなの回答

回答No.2

処理内容がいまいち理解できませんが・・ 重複云々ということで、ロック制御が無いから、併走する複数の処理で 重複が起こる理屈のハズです。 ロック制御を行うためには、トランザクションが前提となります。 トランザクション化したから解決するのでなく、トランザクション化した上で 適切なロック制御が必要です。 >ORCLEでどの様な記述をしたらよいのでしょうか? 具体的な記述については、環境が明らかにならなければコメントできません。  →例えば、oo4o+VBやPL/SQLで、概念は同じでも、書き方は異なります。 また、処理条件を明確にしないとダメだと思います。  →例えば、複数の処理を行うこと自体を禁止したい。のか  複数起動しても良いから、重複して同じデータを処理しなければよいのか、など。

全文を見る
すると、全ての回答が全文表示されます。
  • PrintScree
  • ベストアンサー率25% (538/2091)
回答No.1

そのような場合はトランザクション処理を行います。 oo4oを使っているなら、BeginTrans(だったカナ?)でトランザクション開始を宣言し、テーブルを開く時にトランザクションのモードを指定します。(更新不可、読み取り不可等) 更新終了後にRollbackやComitを行います。 Oracleのマニュアルかヘルプを参照してください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • SQLServerにおける、排他制御に関して質問です。

    SQLServerにおける、排他制御に関して質問です。 環境:  SQLサーバ  ・Windows 2003 Server SP2  ・SQL Server 2005 Standard Edition SP3  SQLクライアント  ・WindowsXP SP3  ・.NET Framework 3.5 SP1 VB.NET アプリ  DBアクセサ  ・ADO.NETを利用 ---------------------------------------------------------------------- 1.DBとのコネクションを確立        ・        ・        ・ 2.データベーストランザクションを開始(レベルはSerializable) 3.テーブルAに対してINSERTを実行   (テーブルAの主キーはオートインクリメント設定されている。) 4.3の結果、追加された主キーを取得するため、MAX()関数にて主キーの最大値(つまり、3で追加した行のはず)を取得 5.テーブルAを外部参照しているテーブルに対して、4で取得したテーブルAのキーを利用して、行を追加・更新などを行う。 6.コミットを行う。   (コネクションは、アプリケーションが終了するまで保持する・・・) ---------------------------------------------------------------------- この処理フローで実行していたシステムですが、 二つのクライアント(X,Y)から、同時に2からの処理が行われた際に排他されず、 Xが、Yが作成したレコードの主キー値を元に、5の更新を行ってしまいました。 ログを見ると、 2→成功 3→成功(別のレコードが作成された) 4→XがMAX関数にて、Yが作成したレコードの主キーを取得   ※処理そのものは成功しているが、論理的におかしい となっています。 論理的には、トランザクションをかけているので、3からの処理が同時に行われるはずはなく、 4で取得される番号も、それぞれが作成した行の主キー番号になるはずなのですが・・・。 論理的に見落としている点や、環境的な要因などで、考えられる原因はありますでしょうか・・・?

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

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

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

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

  • Excelファイルのマクロによる排他制御

    A.xlsというExcelファイルの内容を更新するのですが。 更新しにいくのは、複数のExcelのマクロで作成したツールです。 その複数のツールから同時にA.xlsの更新にいくと当然タイミングによって更新内容が上書き等され壊れてしまいます。 そこで、お互いのツールで排他制御を行おうと思っているのですが、A.xlsを開くopen文での記述が解りません。 どなたか教えていただけないでしょうか。 使用している構文は、こんな感じです。 Workbooks.Open Filename:="A.xls" on errorで重複openのエラーになるかと思ったのですが、エラーになってくれず、重複エラーを検知できません。 よろしくお願いします。

  • 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さんが入力した時に「他のユーザーが使用しています」みたいな メッセージを表示するにはどのようにしたらよろしいでしょうか?? 文章が上手く書けなくてもうしわけありません、 何卒宜しくお願いいたします。

  • 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 ### 以上です。

  • 排他方法

    質問をあげさせて頂きます。 レクチャー頂ければ幸いです。 環境はOSがWindowsXP、DBがOracle9i、開発言語がVB6.0になります。 とあるマスタメンテナンス画面(機能)の開発を行っております。 LOWのUPDATEやDELETE処理を行う前に排他処理を行いたいのですがDbCreateDynasetの引数の実施する必要があります。 サンプルにしているプログラムを見ながら作成しているのですが 下記内容で対象のLOWは排他ロックされているのでしょうか? ORAOBJ.DbCreateDynaset(  s_Sql, '<-更新対象を抽出するSELECT文がセット'  ORADYN_NO_AUTOBIND Or  ORADYN_ORAMODE   Or  ORADYN_NO_BLANKSTRIP ) マニュアルがなく正当性を見出せなかった為、質問させて頂きました。 宜しくお願い致します。

  • 排他処理について

    VBでトランザクションをかけてあるテーブルを処理しています。 具体的にはテーブルAのレコードを一時的に別テーブル(テーブルB)に コピーしてそのレコードすべてを元のテーブルから削除して、 テーブルB内で処理をさせてから、そのデータをテーブルAに戻して コミットしています。 この処理中に、別PGもしくはSQLPlusでテーブルAからテーブルBに コピー対象の1レコードを削除してコミットしました。 これってエラーになる?ならない?それともトランザクション中だから テーブルAがコミットされて開放されるまで待ちの状態になる?? 実際どうなったかというとエラーにならなくて、その処理で最後に テーブルAにテーブルBをコピーしたときにエラーになって データがきえるという現象がおきてしまいました。 上記のような処理のときにOracle条ではどのような処理になるのでしょうか? よろしくお願いします。

  • 【Access】排他モードで利用時のタイムアウト

    社内の部署で共有のアクセスデータベースを作成し、複数の人が同時に編集できないよう、 「排他モード」か「レコードロック」の設定を考えていますが、「排他モード」にした場合、ファイルを 開く時間(タイムアウト)の設定は可能でしょうか?

  • access2010で共有でする

    access2003でDBを分割(テーブル=dbと他=pg)してpgをLAN経由でクライアントにpg_Accessを配布しLANDiscHDDのdb_Accessのテーブルにリンクさせていました。DBのプロパティ設定は、排他・編集済みレコードロックでした。しかし、access2010ではこの方法では、DBを共有してデータを追加・編集・削除ができません。 Web版にはしたくありませんので、良い方法があれば教えて下さい。私は初心者ですのでよろしくお願いします。