@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

複数のメソッドにまたがったトランザクション処理について

1
投稿者投稿内容
水龍蓮
会議室デビュー日: 2004/06/04
投稿数: 8
投稿日時: 2004-06-04 16:09
○開発環境
OS:Windows Server 2003
DB:MS SQL Server 2000

○やりたい事:
ASP.NETのページクラスからデータアクセス用(insert・update等を行う)のクラスへアクセスします、
その時に複数のメソッドを呼び出し、もしinsert・update等に失敗したら各メソッドで
行われたSQLの処理をRollbackすることは可能でしょうか?
可能であればどこを変更したらよいか、ご教授願います。<(_ _)>

↓これにRollback機能をつけたいのです
○データアクセス用クラスのメソッド例(ソース)
コード:
public static object SagyouKanryou()
{
	SqlConnection sqlConn = new SqlConnection(strConn);
	SqlCommand sqlCmd = new SqlCommand();

	switch(groupID)
	{
		case "01":
			H1 = koushinymd;
			H2 = meigara;
			H3 = hinmei;
			H4 = torihikiym;
			H5 = sagyounaiyou;
			H6 = kousu;
			H7 = betusagyoukbn;

			strQuery = "update t02_sagyoumeisai "
				+ "set t02_status = '91', t02_kanryouflg = '1', t02_koushinymd = '" + H1 + "' "
				+ "where t02_meigara =  '" + H2 + "' and t02_hinmei = '" + H3 + "' and t02_torihikiym = '" + H4 + "' and t02_sagyounaiyou = '" + H5 + "' and t02_kousu = " + H6 + " and t02_betusagyoukbn = '" + H7 + "'";
			break;
		case "**":
			同じような処理が複数
			break;
	}
	sqlCmd.CommandText = strQuery;
	sqlCmd.CommandType = CommandType.Text;
	sqlCmd.Connection = sqlConn;
	sqlConn.Open();
	nAffected = sqlCmd.ExecuteNonQuery();
	sqlConn.Close();
	
	return nAffected;
}

一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-06-04 16:14
SqlTransactionクラスを使うと複数のSQL文の実行を一つのトランザクションとしてまとめることができます。

お試しください。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-06-04 16:19
擬似コード:

呼び出し元 {
 DB接続をインスタンス化;
 DB接続を開く;
 トランザクションを開く;
 try {
  SagyouKanryou(DB接続);
  トランザクションをコミット;
 } catch (DbException ex) {
  トランザクションをロールバック;
  エラー処理;
 } catch (Exception ex) {
  トランザクションをロールバック;
  エラー処理;
 } finally {
  DB接続を閉じる;
 }
}

public static object SagyouKanryou(DB接続) { // 受けるの忘れてた
// データベース接続以外はそのまま
}

[ メッセージ編集済み 編集者: Jitta 編集日時 2004-06-04 17:47 ]
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2004-06-04 16:34
もっと、こんな方法があるって意見がでてくることを期待しつつ
私がやってる方法

 通常のメソッドと、Connection,Transactionを渡すオーバロード
バージョンを作って、必要に応じて使い分けています。
コード:
// トランザクション単体の処理バージョン
public void MethodA()
{
	using(SqlConnection conn = new SqlConnection(CONNECT_STR))
	{
		conn.Open();
		using(SqlTransaction tran = conn.BeginTransaction())
		{
			try
			{
			//内部で作成したコネクションとトランザクションで具体的な
			//処理を実行
				MethodA(conn,tran);
				tran.Commit();
			}
			catch
			{
				tran.RollBack();
				throw;
			}
		}
	}
}
// 具体的な処理 、連続したメソッド呼び出しに
//トランザクションの使用が想定されるバーション
public void MethodA(SqlConnection conn,SqlTransaction tran)
{
	string sql ="UPDATE 〜 SET 〜";
	using(SqlCommand comm = new SqlCommand(sql,conn))
	{
		if(tran=!null) comm.Transaction = tran;
		// 何らかの処理
		comm.ExecuteNonQuery();
	}
}



System.Enterpriseservices.ITransaction インターフェイスを実装して
COM+でトランザクション処理させるとか。
こっちは説明できるほど理解できていないので。。。
水龍蓮
会議室デビュー日: 2004/06/04
投稿数: 8
投稿日時: 2004-06-04 17:26
こんにちは、一郎さん。

>SqlTransactionクラスを使うと複数のSQL文の実行を一つのトランザクションとしてまとめることができます。
投稿ありがとうございます、もう少しがんばって調べてみますね^^

こんにちは、Jittaさん。

なるほど!データベース接続も渡すことが出来たんですね、全然思いつきもしませんでした^^;
>// データベース接続以外はそのまま
このようなメソッドが沢山あったのでこのお言葉とてもありがたいです^^
ありがとうございました<(_ _)>

こんにちは、いのつちさん。

なるほど〜、決まったやり方というものは無いのですね^^
とても参考になります、他にもいろいろ方法があれば見てみたいですね。
ありがとうございました<(_ _)>

プログラミング自体が初めてだったのでみなさんの投稿とても心強いです。
皆様から、教えていただいたサンプル等を元にいろいろ試してみます^^
水龍蓮
会議室デビュー日: 2004/06/04
投稿数: 8
投稿日時: 2004-06-14 16:29
みなさんの投稿を参考に処理をすることが出来ましたので報告します。
ありがとうございました。<(_ _)>

ソースコード:
コード:
// データ操作メソッドを呼び出す
public void TRAN()
{
        SqlConnection sqlConn = null;
        SqlTransaction sqlTrans = null;
    
        try
        {
                sqlConn = new SqlConnection(strConn);

                sqlConn.Open();

                sqlTrans = sqlConn.BeginTransaction(IsolationLevel.Serializable);
                
                // データ操作を行うメソッド
                KousuuJouhouTouroku(sqlConn,sqlTrans);
                KousuuJouhouTouroku2(sqlConn,sqlTrans);

                // コミット
                sqlTrans.Commit();
        }
        catch (SqlException sqlExce)
        {
                // デッドロック・エラーのキャッチ。
                if (sqlExce.Number != 1205)
                {
                        // ロールバック
                        sqlTrans.Rollback();
                }
                throw(sqlExce);
        }
        catch (Exception exce)
        {
                // ロールバック
                sqlTrans.Rollback();
                throw (exce);
        }
        finally
        {            
                sqlTrans.Dispose();
                sqlConn.Close();
        }
}
public static void KousuuJouhouTouroku(SqlConnection sqlConn,SqlTransaction sqlTrans)
{
        H1 = meigara;
        H2 = hinmei;
        H3 = torihikiym;
        H4 = sagyounaiyou;
        H5 = kousu.ToString(); //*

        strQuery = "insert into t05_kousu  (t05_meigara, t05_hinmei, t05_torihikiym, t05_sagyounaiyou, t05_kousu) "
                + "values ( '" + H1 + "', '" + H2 + "', '" + H3 + "','" + H4 + "', " + H5 + ") ";

        using(SqlCommand sqlCmd = new SqlCommand(strQuery,sqlConn))
        {
                if(sqlTrans!=null)
                        sqlCmd.Transaction = sqlTrans;

                sqlCmd.ExecuteNonQuery();
        }
}

えムナウ
大ベテラン
会議室デビュー日: 2004/06/10
投稿数: 187
お住まい・勤務地: 東京
投稿日時: 2004-06-15 00:45
サンプルまで作っていただいていた、他のページにも御礼をしておいたほうがよろしいのではないでしょうか?
老婆心ながら・・・(じじいですが)
水龍蓮
会議室デビュー日: 2004/06/04
投稿数: 8
投稿日時: 2004-06-15 15:09
そうですね、わざわざ時間を割いて答えて頂いたのに、お礼を言わないとまずいですよね。
ご指摘ありがとうございます^^
1

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