- PR -

接続型データアクセスでの「1トランザクション内でSELECTと更新系SQLの併用」について

投稿者投稿内容
はね
会議室デビュー日: 2003/03/20
投稿数: 11
投稿日時: 2006-01-15 19:52
Insider.NET 会議室のみなさま、はじめまして。
はね と申します。
Javaから.Netに乗り換えてまだ1ヶ月の.Net初心者です。

以前に kesさん が投稿された下記の記事と同様の内容に
ついてなのですが、

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=18808&forum=7

この記事のやり取りでは結果的に「接続型データアクセス
ではやらない(できない)」といった解答に落ち着いている
ようなのですが、もし更新系SQLの元となるSELECTの結果
セットが大量な場合、インメモリでデータを保持する非接
続型データアクセスだと都合が悪いようなケースも多々あ
ると思うのですが、そのような場合.Netではどのような解
法が考えられるのでしょうか?

Javaをやっていた頃はResultSetをループさせながら同一
コネクションで更新系SQLを発行する処理は普通にやって
いたため(そもそも非接続データアクセスは言語レベルでは
サポートされていない)、「接続型データアクセスではやら
ない」というkesさんの記事の解答について、.Netに不慣れ
な私としては非常に不便なように感じてしまいます。

なお、この質問は非接続データアクセスを否定するものでは
ありません。また、純粋に.Netについての技術的な質問です
ので、特に具体的な実行環境や処理詳細があるわけではあり
ません。また、「ストアドプロシージャーを使うべき」など
の多言語による解決方法を期待するものでもありません。

以上、よろしくお願いします。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-01-15 23:30
引用:

.Netに不慣れな私としては非常に不便なように感じてしまいます。


 まあ、難しいトコですね。
究極的には、ADO.NETとJDBC設計時の価値観、設計思想、プログラミングモデル上の選択の違いちゅう話ですから。

Javaは「同じデータの操作なんだから同一ループ内で読み取り、更新できるんちゃうん。」
.NETは「読み取りが終わったら変更。変更が終わったら更新の方が自然やん。」
みたいな。

 これはアプリケーション開発時にプログラムの構造の与え方に影響をおよぼすでしょうが
引用:

もし更新系SQLの元となるSELECTの結果セットが大量な場合、
インメモリでデータを保持する非接続型データアクセスだと都合が悪いようなケースも多々あると思う


くらいの話だったら処理対象を分割するとかアプリケーション側の設計で可能な限り吸収したいところです。

参考:
「ADO.NET パフォーマンスの向上」
『 .NET アプリケーションのパフォーマンスとスケーラビリティの向上』
http://www.microsoft.com/japan/msdn/enterprise/pag/scalenetchapt12.asp#scalenetchapt12_topic13
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2006-01-16 10:09
こんにちは、kanaiです。

きれいな方法とは思いませんが、DataReaderを読みながら更新する場合は、
仕方ないので別に更新用のコネクションを開きます。

ただし、元記事にもあるように、元のコネクションで未コミットのデータは
更新用のコネクションには反映されないので、そのような状況には使えません。
lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-01-16 11:06
引用:

きれいな方法とは思いませんが、DataReaderを読みながら更新する場合は、
仕方ないので別に更新用のコネクションを開きます。

ただし、元記事にもあるように、元のコネクションで未コミットのデータは
更新用のコネクションには反映されないので、そのような状況には使えません。


 それは…プログラムの意味が違っちゃうのでマズいのでは…。
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2006-01-16 11:29
kanaiです。

>lalupin4さん

引用:

それは…プログラムの意味が違っちゃうのでマズいのでは…。



コネクションを別にしても、整合性を失わない状況であれば、
使用可能だと思いますが・・・

他にどのような点がマズイのでしょうか?
ご教示いただければ幸いです。

なお、少し調べてみたところ、Oracle + ODP.NETを使用すると、
同一コネクション内でDataReaderを開いたまま、別のDataReaderを
開いたり、更新SQLを実行したりできるようです。
("MARS"という機能だそうです。)

lalupin4
大ベテラン
会議室デビュー日: 2004/07/26
投稿数: 163
投稿日時: 2006-01-16 11:43
引用:

コネクションを別にしても、整合性を失わない状況であれば、
使用可能だと思いますが・・・


 そりゃ、コンパイルも実行もできるでしょうが
「失っちゃうかもしれない状況」でそれができないから困ってるわけで。
引用:

プログラムの意味が違っちゃう


というのはそういう意味です。

タイトルがそもそも
引用:

接続型データアクセスでの「1トランザクション内でSELECTと更新系SQLの併用」について


ですから。

ケチつけたようなカンジになってごめんね。ごめんね。
trapemiya
大ベテラン
会議室デビュー日: 2005/07/30
投稿数: 102
投稿日時: 2006-01-16 11:56
引用:

はねさんの書き込み (2006-01-15 19:52) より:
もし更新系SQLの元となるSELECTの結果
セットが大量な場合、インメモリでデータを保持する非接
続型データアクセスだと都合が悪いようなケースも多々あ
ると思うのですが、そのような場合.Netではどのような解
法が考えられるのでしょうか?


上ではねさんが言われているようなことは、バッチ処理的であり、もし、接続型のデメリット(ロックや接続資源の問題など)が許容できるのであれば、接続型がむしろ適していると思います。そのために、ADO.NETではDataReaderという接続型のオブジェクトが用意されています。
いずれにしても、接続型と非接続型はどちらが良いというわけではなく、それぞれに得意分野があると思います。接続型のデメリットは多くの場合、データを読んだ後に人間による処理がある場合に発生するのではないでしょうか?ですから、そういう状況でなければ、接続型で処理する方が効率的だと思います。
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2006-01-16 13:06
kanaiです。

>lalupin4さん

すいません。「トランザクション内で」という条件を失念、というか軽く考えていました。「意味が違ってしまう」という点もよく分かりました。

ただ、私ならばやはり
・読取専用コネクション
・更新用コネクション(こちらでトランザクションを管理)
という構成にしてしまいそうです。
(もちろん、整合性を失わないように諸条件を整える必要がありますので、
使用できるかは状況によります)

上記のような面倒なことをしなくてすむように用意されたのが"MARS"だと思うのですが、
いかがでしょうか?

引用:

ケチつけたようなカンジになってごめんね。ごめんね。



ぜんぜん気にしていませんので、お気になさらないでください。

スキルアップ/キャリアアップ(JOB@IT)