質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

Q&A

解決済

3回答

2788閲覧

C# Oracleセッションを跨いでの排他制御

退会済みユーザー

退会済みユーザー

総合スコア0

DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

0グッド

0クリップ

投稿2020/10/15 19:59

DataSetを使用してデータベースからデータを取得しているのですが、その際の排他制御に関して質問です。
###実現したいこと
Form1:SQLを発行しデータ取得,Form2に表示

Form2:データ閲覧 データに対して変更を加える

SQL発行し、データベースに反映

上記フローのデータ取得時からデータベースに反映までの間,排他制御を行いたい。

質問内容

上記のようにセッションを跨いで排他制御をかけたいときは、
悲観的排他制御ではなく楽観的排他制御を使用したほうがいいのでしょうか?


初歩的なことかもしれませんがご回答くださると助かります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

悲観的排他制御ではなく楽観的排他制御を使用したほうがいいのでしょうか?

どちらがいいかは状況が分からない第三者には分かりません。

言葉の通り「楽観的」(あまり同時実行は起こらないし、起こってもユーザーにその旨通知してキャンセルすれば許される) でよければ、楽観的同時実行制御一択だと思います。

Visual Studio のデータソース構成ウィザードで型付き DataSet/DataTable + TableAdapter を作れば、楽観的同時実行制御の機能をほとんどコードを書かなくても実装できます。

ちなみに、SSMS には同時実行制御の機能が付いていて、編集作業を行っているときに、更新をかける前に他で変更されていたりすると、その旨メッセージが表示されます。

【追記】

追加情報を書いておきます。

以下の記事が参考になると思います。特に「楽観的同時実行制御と悲観的同時実行制御」のセクションを見てください。

DB 設計者のための明解 ADO.NET 第 1 回
https://docs.microsoft.com/ja-jp/previous-versions/cc482903(v=msdn.10)

質問者さんは DataSet を利用した非接続型アクセスを行っているようですが、であれば、そこに、

"DataSet の DataAdapter 経由の更新においては、非接続データアクセスと楽観的同時実行制御が基本となっており、それをベースにシステム実装を図ると、自ずとスケーラビリティの向上が図れる"

・・・と書いてありますように、楽観的同時実行制御の採用をまず考えることをお勧めします。

上にも書きましたが、Visual Studio のデータソース構成ウィザードで型付き DataSet/DataTable + TableAdapter を作れば、楽観的同時実行制御の機能をほとんどコードを書かなくても実装できます。

イメージ説明

投稿2020/10/15 23:03

編集2020/10/16 01:07
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/10/16 10:08

ご回答ありがとうございます。 参考サイトまでありがとうございます。 このような機能があるとは知りませんでした。。。 一つ気になったのですが、DataSet/DataTable + TableAdapterでの非接続データアクセスは古いのでしょうか? 色々な参考サイトを見ていても更新日時がかなり前のものばかりで気になりました。
退会済みユーザー

退会済みユーザー

2020/10/16 10:15

> 一つ気になったのですが、DataSet/DataTable + TableAdapterでの非接続データアクセスは古いのでしょうか? 古いというより昔からある方法と言った方が当たっていると思います。Windows Forms アプリで DataGirdView などを UI にして、ADO.NET を使って DB の表示・編集・更新操作を行うなら、選択肢の一番に来ると思います。
退会済みユーザー

退会済みユーザー

2020/10/16 10:48

ご回答ありがとうございます。 >古いというより昔からある方法と言った方が当たっていると思います。 そうなんですね。ありがとうございます。 まだ、プログラミング自体学習を始めたばかりなので実際に作業していること以外のことも学習し精進していきます。 今回ベストアンサーとさせていただきました。 今後お世話になるかもしれませんが、その際はよろしくお願いします。
guest

0

どういうロックが必要かは必要要件で変わってきますので何とも言えませんが、
セッションを跨ぐ場合、同時編集させたくない編集画面のレコードをロックテーブルで判定するというのをやった事はあります。

  • ロックテーブルに更新対象のプライマリーキーでinsertできたユーザーだけ編集出来るようにする
  • ロックしたユーザー、ロック時間等の付加情報も付けておく
  • 編集画面が終わった時点でロックテーブルのレコードを削除する
  • 編集中にアプリ(PC)が落ちた場合はロックテーブルのレコードが残るので、何らかの解除手段は用意する

投稿2020/10/16 00:19

編集2020/10/16 00:22
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/10/16 10:42

ご回答ありがとうございます。 なるほど、実際に実装したことを書いてくださりありがとうございます。 すべての方にベストアンサーをつけたいですが今回は別の方につけさせていただきます。ありがとうございました。
guest

0

SELECT 時に明示的な行ロックを行なう方法 を参考に。

COMMIT ;
で確定して、ロックを解除します。

ROLLBACK ;
更新を取り消して、ロックを解除します。(エラー時の取り消し用途)

過去、100本以上のPL/SQLでテーブル1つ毎のCOMMITしているとんでもない作られたシステムを見たことがあります。お客様には詐欺にあったという自覚は持ちましょう、と伝えて1日で調査を終わりました。

投稿2020/10/15 20:30

Orlofsky

総合スコア16417

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/10/15 20:50

ご回答ありがとうございます。 質問なのですが 悲観的排他制御をおこなう場合セッション終了ごとにCOMMITが暗黙的に実行されると思うのですが、フロー完了までの間を1つのセッションと考えデータベースとの接続状態を保持したままにしてよろしいのでしょうか? 参考サイト等見ていると、あまり接続状態を保持し続けるのはよくないと書かれているのでこの考え方はよくないと思っていたのですが...
Orlofsky

2020/10/15 23:51

ロック待ちで許容できる時間がシステムによってかなり違うのでどっちが良い、というものではありません。 例えば、短時間の内に複数のsessionから同じ口座への入出金が多数あるシステムであるsessionが口座を長時間ロックしたままだと他のsessionがロックの解除待ちで止まってしまいますから、好ましくありません。銀行関係のシステムでは明示的ロックしか見た記憶がありません。 質問に用途と共に参考サイトのURLを追記した方が適切なコメントが付きやすいかと。 なお、Oracle Database では明示的ロック、暗黙的ロックという書き方は普通にありますが、悲観的排他制御、楽観的排他制御と書くドキュメントはあまりないです。 5年くらい前まではロック方法でかなり頻繁に方式設計に呼ばれましたが、最近は方式設計さえまともにしないで、排他制御さえ知らないプログラマーが書いたSQLが総合テストでも引っかからないで本番環境で実行されて大きなバグを起こす事が多いように思えます。
退会済みユーザー

退会済みユーザー

2020/10/16 10:38

なるほど。 自分も構想段階で排他制御に関しては全然知らずやっていくうちに同時更新等があったときにどうするのかな?と疑問に感じ調べ始めて今回の質問をさせていただきました。 回答をしていただいた者としてはすべての方にベストアンサーをつけたいのですが、今回別の方につけさせていただきます。 すみません、参考サイトに関してはどのサイトか忘れてしまいまして... 今後添付できるよう控えておきます。 完全独学で三か月前からシステム開発を始めたので、またお世話になるかもしれませんがよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問