C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: トランザクションの維持


(過去ログ 11 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■2661 / inTopicNo.1)  トランザクションの維持
  
□投稿者/ ライト (1回)-(2007/04/13(Fri) 10:36:08)

分類:[C# (ASP.NET)] 

こんにちわ。

トランザクションの実装方法について、ご教授いただければと書込ました。

今までは1トランザクションで完結していて、細かいところは省略しますが大凡

SqlTransaction sqlTran;

using (SqlConnection sqlCon = new SqlConnection(CONNECTION)) {
sqlCon.Open();
sqlTran = sqlCon.BeginTransaction();
using (SqlCommand sqlCmd = new SqlCommand("SQL文"), sqlCon, sqlTran) {
try {
sqlCmd.Parameters.AddWithValue(パラメータ設定);

if (sqlCmd.ExecuteNonQuery() >= 1) {
sqlTran.Commit();
return true;
} else {
sqlTran.Rollback();
return false;
}
} catch (Exception ex) {
sqlTran.Rollback();
return false;
} finally {
sqlCon.Close();
}
}
}

こんな感じでやっていました。
1件(1処理)だけだったのでこれで良かったんですが、複数回実行する必要が出てきました。
その時、全て成功だったらコミットで、どれか一つでも失敗したらロールバックしようと思っています。
ですが上記の方法では1回成功しただけでコミットしてしまっているので、この関数をループで呼び出しても
当然1処理事にコミットしてしまいます。

となるとトランザクションを外出しにして、この関数にトランザクションを引数として渡し
全てtrueだった場合に、関数を呼び出した側でコミットorロールバックしようと思ってるんですが
これだとトランザクション系がクラスではなく、apsx(ascx)の.cs部分に記入する事になります。
いわゆるaspxとかには表示だけの処理、実際の処理は関数を呼び出すだけで、本体は別ファイルのクラスの中。
そういう構造でやってるんですが、トランザクションを外出しにするとこれではなくなってしまいます。

何かいい方法はないでしょうか?
思いついたのは呼び出し側と実処理クラスの間にもう一つ挟んで、それをaspxから呼び出すというものです。
今はaspx→処理クラス(今回の関数)を直接呼んでいますが これを
aspx→トランザクション処理だけするクラス→処理クラス(今回の関数)としようと思ったんですが
これだと真ん中の部分が汎用性のないクラスになってしまいます。
ループするわけなので、ここでループ処理とaspxから渡された引数等の処理もしないといけないので
固定された引数等にしか対応できなくなるので。
このトランザクションの部分をどんなSQLでも、パラメータが変わっても対応できればそれが最高なんですが・・・

もっと便利な方法があったりするでしょうか?
引用返信 編集キー/
■2666 / inTopicNo.2)  Re[1]: トランザクションの維持
□投稿者/ 中博俊 (1022回)-(2007/04/13(Fri) 11:31:25)
中博俊 さんの Web サイト
配列を受ける版を作成すればいいでしょう。
トランザクションもADO.NETのそれを利用するなら、SqlConnection, SqlCommandを使い回す事にするか事になるかもしれませんが、System.Transactionを利用すれば簡単です。(遅いけど)


引用返信 編集キー/
■2673 / inTopicNo.3)  Re[2]: トランザクションの維持
□投稿者/ 囚人 (79回)-(2007/04/13(Fri) 12:16:36)
囚人 さんの Web サイト
>思いついたのは呼び出し側と実処理クラスの間にもう一つ挟んで、それをaspxから呼び出すというものです。
>今はaspx→処理クラス(今回の関数)を直接呼んでいますが これを
>aspx→トランザクション処理だけするクラス→処理クラス(今回の関数)としようと思ったんですが
>これだと真ん中の部分が汎用性のないクラスになってしまいます。

そういう感じで良いと思いますよ。やたらめったらに汎用化しようとすると破綻します。
トランザクションというものは、特定の業務の特定の業務処理に特化して当たり前です。
あるデータを単に SELECT するだけでも、分離レベルはどうするか、更新予約はしておくべきか等考慮する事は盛り沢山です。
汎用化すると、セーブポイントまで戻れば十分なのに全部ロールバックしてしまうとか、デッドロックが避けられないだとか、そんな事になります。
もちろん、それなりの設計力があれば上手にクラス化できると思いますが、なかなか難度が高いかと思います。
引用返信 編集キー/
■2725 / inTopicNo.4)  Re[3]: トランザクションの維持
□投稿者/ ライト (2回)-(2007/04/13(Fri) 19:52:34)
>配列を受ける版を作成すればいいでしょう。
知識不足で、中さんの言わんとすることが理解できなかったのですが
配列とは、何を配列として受け取るんでしょう?
関数自体はこのままで、ここに渡されるパラメータを配列で渡し
この関数内でループさせるということでしょうか?

> そういう感じで良いと思いますよ。やたらめったらに汎用化しようとすると破綻します。
> トランザクションというものは、特定の業務の特定の業務処理に特化して当たり前です。
> あるデータを単に SELECT するだけでも、分離レベルはどうするか、更新予約はしておくべきか等考慮する事は盛り沢山です。
> 汎用化すると、セーブポイントまで戻れば十分なのに全部ロールバックしてしまうとか、デッドロックが避けられないだとか、そんな事になります。
> もちろん、それなりの設計力があれば上手にクラス化できると思いますが、なかなか難度が高いかと思います。
なるほど。
たいした技術も知識もまだないので、汎用性のことはひとまず置いておこうかと思います。
汎用化の前にまずトランザクション自体、DB自体の扱い方をもっと学んだ方がよさそうですね。
引用返信 編集キー/
■2728 / inTopicNo.5)  Re[4]: トランザクションの維持
□投稿者/ はつね (134回)-(2007/04/13(Fri) 20:32:59)
はつね さんの Web サイト
No2725 (ライト さん) に返信
> 関数自体はこのままで、ここに渡されるパラメータを配列で渡し
> この関数内でループさせるということでしょうか?

SqlCommandを使ったときの基本的なトランザクションの基本的な使い方は次のようになります。

sqlTran = sqlCon.BeginTransaction();
try {
 (ここで1つのトランザクションに含みたいSQL文を次々に実行)
  sqlTran.Commit();
  return true;
} catch (Exception ex) {
  sqlTran.Rollback();
  return false;
} finally {
  sqlCon.Close();
}

複数のSQL文を実行する手段として配列を使ってループするというのも1つの方法です。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -