- - PR -
1トランザクション内でSELECTとUPDATE
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-02-07 08:57
MSDNヘルプにも記載されているように、それがDataReaderの仕様です。従って、別の方法を考える必要があります。皆さんがおっしゃっているように、 ・DataReaderの代わりにDataSetを使う ・DB側で実装する(ストアド、トリガー等) などの方法があります。 PL/SQLが記述できるなら、DB側で実装するのが簡単だと思います。 | ||||||||
|
投稿日時: 2005-02-07 12:05
DataReaderにこだわらなければならない理由も特に感じられません。
ADO.NETに関してもう少し調査をされたほうが良いのでは? ↓など。。 http://www.microsoft.com/japan/msdn/thisweek/meikaiADONET/default.asp DBトリガーも”Kesさん”のお望みの機能からすると簡単便利で利点があります。 トリガーの危惧される点は、DBサーバーのその時折のパフォーマンスにより トリガーのcommitのタイミングもアプリケーション側から見ると不定になるので、 多用すると障害調査などは複雑になりがちです。 パッケージシステムで拡張性がないのならトリガーでもよいですが、 将来拡張性を求めるシステムならば、システム早期の設計でトリガーを利用しない方法を検討したほうが失敗が少ないと思います(私的経験から・・) 最初にDBトリガーでの更新などを仕込むと、拡張仕様が出てきたときに トリガー更新からの別トリガーでの別更新などをDBに仕込まざるおえない事情が発生する等・・ のプログラマからは調査が難解な領域を多数埋め込むシステムになりかねないと思います。。 また、DBはOracleということなので、Oracle Data Provider for .NET(ODP.NET)など Oracle社自身が出しているOracleに最適化されたDBプロバイダーも提供されており、 MS:OleDBよりも、MS:OracleClient(System.Data.OracleClient)よりもパフォーマンスが良いとされています。 DB接続プロバイダーの変更はコードの作成が完了してからでは面倒なところも多くあります。 (※最初から複数のDBプロバイダーを使うことを想定してコードを書くなら別ですが・・) ADO.NETを使用するにも、プロバイダーの選択や 検索・更新手法も1つの考え方に固執しない方がよいと思いますが・・。 | ||||||||
|
投稿日時: 2005-02-07 13:07
みなさま、いろいろとありがとうございます。
もうシステムの出荷まで時間がありませんので、いまからPL/SQLを勉強して、トリガやストアドを作る余裕はないので、DataAdapterを使うか、Datasetを使うかしようと思います。 しかしDatasetですが、いまひとつ存在する理由がよく分かりません。 DataTableは使っているのですが、DataSetを使うとどんなメリットがあるのでしょうか。 | ||||||||
|
投稿日時: 2005-02-07 13:47
従来のデータベースアクセスを密結合データアクセスとするなら、疎結合データアクセスとでも言えばよいのでしょうか? 例えばクライアント数が非常に多い場合、密結合ではデータベースの負荷が大きくなってしまいます。またインターネットのような不安定なネットワークを介したアクセスの場合、クライアントとの接続が突然切れたり、不安定になる可能性もあります。WEBサービスの場合、WEBクライアントは正常な終了処理をすることなく突然居なくなる事が当たり前に起きます。 こういった性質をもつアプリケーションを密結合、つまり常に接続状態を維持し、必要なときにデータを取得する方法で実装するのは困難です。もし作るとサーバーへの同時接続数は極端に増え、たびたびテーブルはロックされたままになり、アプリケーションは処理を継続できなくなるでしょう。 必要なデータは事前にローカルに複製、サーバへ接続するのは更新や取得の為に瞬間だけとすれば上記の問題の多くは解決されます。これを実現するための仕組みがDataSetです。 _________________ 甕星 <mikahosi@abox9.so-net.ne.jp> http://blogs.msmvp.jp/mikahosi/ | ||||||||
|
投稿日時: 2005-02-07 14:02
ども、ぼのぼのです。
甕星さん、これはDataReaderとDataSetの違いでは?(^^; kesさんの質問をよく見ると、DataTableとDataSetの違いを聞いてますよね? DataTableとDataSetは両方とも疎結合データアクセスで、DataSetは簡単に言うとDataTableのコレクションです(よね?)。で、聞かれているのは一回のSELECT文の実行結果は一つのDataTableという形になるのが普通なのに、なぜDataTableのコレクションという形で取得する必要があるのか、ということなのではないでしょうか? 実は私も同様の疑問を持っています。誰か分かる方いらっしゃいましたら、教えて頂けると幸いです。 | ||||||||
|
投稿日時: 2005-02-07 14:50
DataTableは、DataSetの下位に存在するオブジェクトです。 DataTableだけで済むのであれば、それで十分なシステムだということです。 今回の”kesさん”のシステムでは単体のテーブルのみが対象で、 DataSetのというテーブルの集合・制約・リレーションの定義を含めたものまでも格納できる メモリ上のDBのようなオブジェクトの必要性を感じないだけであって、DataSetの存在は私は肯定します。(※DataSetはテーブル単体の集合だけではありません) 異なるDBから実際に存在しない仮想DBもメモリ上で作成できますし 新たな制約の定義もできます。 たとえば、複雑なDB構成を持つシステムや、既存の複数システム間のデータ関連付け(検索・更新)も1つのDataSetというオブジェクトで行えるようになるので有用性はあると思います。 システム設計の難しさに ・既存のデータをどうするのか? ・自分たちのシステムには情報は無いが、別のシステムには既にデータがある場合どうするか? という問題に対して、 データのコピーという2重資産を持つと、 一方の情報との同期が問題になり、資産としてDB領域・データ同期を取るためのシステムの作成など、・・同じ情報に対して無駄ともいえるもの提供しがちになります。 メインの必要な情報は自分のDBから、これに関連される別の情報は既存システムから・・などのシステム(DB)を超えた新たなシステムを作り出せますよね。 以上、たとえ話と夢(?)でしたが、DataSetのようなオブジェクトがあることで、 システム設計上、「無謀」とか「作り変えのほうが早い」と言われていたシステムの問題を 「ある程度カバーできる」と言う可能性を感じさせるものだと思っています。 ただし、DB非接続型となるため、メモリの浪費という問題が発生し得るので、 大量データの場合はプログラマーの独断に寄らず、 システム構成(サーバスペックやネットワーク帯域等)を考慮した オブジェクト使用法やアプリケーション設計が必要だと思いますが・・。 [ メッセージ編集済み 編集者: xxななおxx 編集日時 2005-02-07 15:43 ] | ||||||||
|
投稿日時: 2005-02-07 15:17
またやってしまったorz おそらく「SELECT文で結合したDataTableを取得するのではなく、複数のDataTableとDataRelationとして活用して欲しいのかな」もしかしたら「将来的に複数のDataTableとDataRelation、etcを返すようなインターフェースを提供するつもりなのかな」と考えてます。 DataSetは単純なテーブルの集合ではなく、データベースにおけるRelationや制約をメモリ上にそのまま再現するための仕組みです。複雑なリレーションを持つテーブルを結合した状態で持つのはメモリを無駄に浪費しますが、複数のテーブルとリレーションという形で保持すればメモリを節約できます。また複数のレコードからRelationを張られたレコードへの更新を、オフラインのまま無駄にループ処理を行うこと無く実現できます。後でデータベースにUpdateするのも楽になるはずです。その他にも活用出来る場は多々あるかと。 と言いつつ、単なるDataTableとしてしか使っていないことのほうが圧倒的に多いのですけど。 _________________ 甕星 <mikahosi@abox9.so-net.ne.jp> http://blogs.msmvp.jp/mikahosi/ | ||||||||
|
投稿日時: 2005-02-07 20:16
私もyaさんの「DBにやらせる」を支持します。「PL/SQL」、「ストアドプロシージャ」をキーに、マニュアルを漁ってください。OracleのマニュアルはPDFなので、検索しにくいですが、丁寧に書いてあります。
ただ、そうすると2つの言語を覚えなければならないことになり、しんどいと思います。なので、データベースに戻さずに、VB.NET上ですべて処理する方法も、提案します。
Aから更新しなければならないデータを、DataTableに抽出します。この、抽出したDataTableに対して更新をかけます。次に、これによって影響を受けるB,Cのデータを抽出します。抽出したら、更新します。これらのDataTableが更新できたら、UPDATE文を3回流します。こうすれば、“データベースからAを読みながら”という処理がなくなるので、Readerを閉じろというエラーからは解放されます。 データセットは・・・一つの「データベース」と考えてください。もしくは、「データテーブルの入れ物」とか。この中で、中に保持するテーブル間のリレーションシップを定義できます。 しかし、B,Cについては、ビューを使えばテーブルを構成する必要はないようにも思います。ビューにしておけば、更新する必要はありません。ビューの元になったテーブルが更新されれば、即時に更新されます(マテリアライズドビューは除く)。テーブルB,Cの更新内容が、Aを単純に計算/集計すれば出てくるものであるなら、都度SELECT文を発行するとか、ビューに構成するだけでかまわないように思います。 んと、私の場合、発信制限があるので、書いているとき=発信しているとき、ではありません。スレッド全体からすると過去に戻っていますが、堪忍してください。 _________________ |