- PR -

OLEDBでのトランザクション処理の関連付けについて

投稿者投稿内容
Iuret
会議室デビュー日: 2006/05/15
投稿数: 13
投稿日時: 2006-05-15 19:38
はじめまして。.NETでの開発2年目になります。
トランザクションの処理についてお聞きしたい事があります。
OLEDBでコマンドを投げる処理(トランザクションに含めた)を行い結果を
Boolean型で返すような関数を作っているのですが、
さらに利便性の向上をしたいと思い、引数にトランザクションを割り当てなくても、
トランザクションに含めた処理をできるようにしたいのですが、可能でしょうか?
どなたか知っている方、ご教授お願い頂けませんでしょうか?
よろしくお願いしますm(_ _)m

↓以下が問題の関数

///////////////////////////////////////////////////////////////////////////////////////////
コード:
Public Function Execute(ByVal m_Con As OleDbConnection, ByVal strSQL As String,_ 
<<<Optional ByVal m_Tran As OleDbTransaction = Nothing>>>←ここを省略したい) As Boolean

         Dim m_Cmd As OleDbCommand
         Dim blnFlg As Boolean = False

         Try

                  m_Cmd = New OleDbCommand(strSQL, m_Con)
                  m_Cmd.CommandType = CommandType.Text

                  <<<m_Cmd.Transaction = m_Tran>>>←ここを省略したい

                  m_Cmd.ExecuteNonQuery()

                  blnFlg = True

         Catch ex As Exception
                  Throw (ex)
         Finally
                  Execute = blnFlg
         End Try
End Function


///////////////////////////////////////////////////////////////////////////////////////////

※トランザクションは関数前にDim m_Tran As OleDbTransaction = m_Con.BeginTransaction()で開始済みを前提としています。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-15 20:12
引用:

Iuretさんの書き込み (2006-05-15 19:38) より:

OLEDBでコマンドを投げる処理(トランザクションに含めた)を行い結果を
Boolean型で返すような関数を作っているのですが、
さらに利便性の向上をしたいと思い、引数にトランザクションを割り当てなくても、
トランザクションに含めた処理をできるようにしたいのですが、可能でしょうか?


一連の流れとしてトランザクション処理を実装するのであれば、Transaction は同一でなければなりません。
引数かどうかはともかく、何もない状態では同一の Transaction を求められないので無理ですね。

回答としては、ラッパークラスに Transaction をメンバとして設けて利用する。
になるのではないでしょうか?

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Iuret
会議室デビュー日: 2006/05/15
投稿数: 13
投稿日時: 2006-05-15 20:43
ご返答ありがとうございます!m(_ _)m
引用:

回答としては、ラッパークラスに Transaction をメンバとして設けて利用する。
になるのではないでしょうか?


と、書かれていますが「ラッパークラス」というのあまりわかってないんですが
親クラスにメソッドを定義して、この関数に継承するってことですか?
勉強不足です。すいません。m(_ _)m
そこらへんだけもうちょっと詳しく教えて頂けませんか?
よろしくお願いします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-15 21:14
引用:

Iuretさんの書き込み (2006-05-15 20:43) より:

と、書かれていますが「ラッパークラス」というのあまりわかってないんですが
親クラスにメソッドを定義して、この関数に継承するってことですか?
勉強不足です。すいません。m(_ _)m


いえ、クラスに Execute メソッドを含め、メンバとして Transaction も含めるということです。
単一トランザクションにしか対応できませんが、こういう方法もありますということです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-05-16 02:32
僕が一番最初にOleDB を使った時、いろいろ手続きが大変だなぁ〜、と思ってやった
のが、じゃんぬねっとさんの言うクラスにする方法でした
ちょっとした SQL 指定して実行する程度なら軽快に使えて便利ですが、単独で実行
するだけなので考えてみるとトランザクション処理しなくて良い場合もあったり・・・

Iuret
会議室デビュー日: 2006/05/15
投稿数: 13
投稿日時: 2006-05-17 19:11
返答が遅れてすいません。
じゃんぬねっと、R・田中一郎さんご返答ありがとうございます。m(_ _)m
Executeが存在するクラスの中でトランザクションがメンバとして存在するなら可能なんですよね?
しかし、Executeが存在しない別のクラスでコネクションを開き、トランザクションを開始して、
Executeが存在するクラスでトランザクション処理しようとするならば、
Executeの引数にトランザクションを開始したコネクションとトランザクションは必須という事とですよね?

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-17 19:27
引用:

Iuretさんの書き込み (2006-05-17 19:11) より:

しかし、Executeが存在しない別のクラスでコネクションを開き、トランザクションを開始して、
Executeが存在するクラスでトランザクション処理しようとするならば、
Executeの引数にトランザクションを開始したコネクションとトランザクションは必須という事とですよね?


うーん、ちょっと違いますね...
むしろ逆のことを言っていたつもりでした。
すみません、どうも説明が下手だったようです。

そのラッパークラスで、Transaction を開始するメソッドを公開しておけば、1 度で済むということです。

以下はラッパークラスを使用した場合のイメージです。(OleDbWrapper クラスとします)

コード:

    Dim wrapper As OleDbWrapper

    Try
        wrapper = New OleDbWrapper()
        wrapper.Open("[接続文字列]")

        ' トランザクションを開始する (これ 1 回のみ)
        wrapper.BeginTransaction()

        wrapper.Execute("[好きな SQL コマンド 1]")  '何かの更新 1
        wrapper.Execute("[好きな SQL コマンド 2]")  '何かの更新 2
        wrapper.Execute("[好きな SQL コマンド 3]")  '何かの更新 3
        wrapper.Execute("[好きな SQL コマンド 4]")  '何かの更新 4

        ' コミット
        wrapper.Commit()
    Catch
        ' 例外発生時はロールバック
        wrapper.Rollback()
        Throw
    Finally
        ' コネクションの破棄など後始末
        If Not wrapper Is Nothing Then
            wrapper.Dispose()
        End If
    End Try


ご覧のとおり、Execute メソッドで Transaction を渡していません。
OleDbWrapper クラスで Transaction "も" 管理するという意味でのラッパークラスです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Iuret
会議室デビュー日: 2006/05/15
投稿数: 13
投稿日時: 2006-05-17 20:44
早いご返答ありがとうございます!m(_ _)m 感謝します。

今、私は「OleDbWrapper」見たいなクラスライブラリを作成していて、
じゃんぬねっとさんが言うようなクラス内でトランザクションを管理した
処理はできているんです。
しかし、こういうケースだったらどうですか?


コード:

    Dim wrapper  As OleDbWrapper
    Dim m_Tran as OleDbTransaction
    Dim m_Con as OleDbConnection

    Try
        wrapper = New OleDbWrapper()

        wrapper.Open("[接続文字列]")

        ' トランザクションを開始する (これ 1 回のみ)
        m_Tran = wrapper.BeginTransaction()

        UpdateData(m_Con,"[好きな SQL コマンド]",m_Tran) 
        ↑※m_Conだけ渡して、ここのm_Tranを省略したいです。


        ' コミット
        wrapper.CommitTrans(m_Tran)

    Catch
        ' 例外発生時はロールバック
        wrapper.RollbackTrans(m_Tran)
        Throw
    Finally
        ' コネクションの破棄など後始末
        If Not wrapper Is Nothing Then
            wrapper.Dispose()
        End If
    End Try


↓UpdateData関数簡易詳細
////////////////////////////////////////////////////////////////////////////////

Private Sub UpdateData(Byval m_Con as OleDbConnection,Byval strSQL as String,_
Byval m_Tran as OleDbTransaction)

        Dim wrapper2 As OleDbWrapper

        wrapper2 = New OleDbWrapper()

        //////////////////
        何らかの処理(省略)
        //////////////////

        'wrapper2内の管理ではコネクションは開いてなく、トランザクションを開始していないです

        wrapper2.Execute(m_Con,"[好きな SQL コマンド]",m_Tran)  
        ↑※m_Conだけ渡して、ここのm_Tranを省略したいです。


        //////////////////
        何らかの処理(省略)
        //////////////////

End Sub
////////////////////////////////////////////////////////////////////////////////




※CommitTransとRollbackTransは引数に「ByVal m_Tran As OleDbTransaction = Nothing」
と記述してあり、CommitTransはm_Tranに対してCommit、RollbackTransはm_Tranに対してRollbackの
処理をしている関数と思ってくれたら結構です。
 Executeは前の書き込み通りです。

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