fc2ブログ

(元)社内SEの徒然なる日記

oo4oでトランザクションを使ってみた

トランザクション

oo4o(Oracle Objects for OLE)でもトランザクション(transaction)は使えます。

ちなみにトランザクションとは、確定(コミット)前であれば、DML文(Insert、Update、Delete)の実行を取り消す(ロールバック)ことが出来る処理のことです。

もう少し細かく言うと、処理の一貫性をを保つもので、処理が完全に終了するか、まったく実行されない状態にするかの、どちらかの結果になることを保証するものです。
まぁ、システム屋で「トランザクションって何?」って人に出会ったことが無いので、説明は不要ですよね?

ともあれ、今回はこれを試してみます。

サンプルソース

内容は前回とほとんど同じです。
トランザクションを制御する処理と、エラートラップの追加だけです。


' データ登録サンプル(CreateSQL:トランザクション)
'
Sub insertTestCreateSQLTransaction()
On Error GoTo systemError

'--------------
' 変数宣言
'--------------

'SQL文
Dim mySql As String

'登録データ
Dim myTbl(2, 1) As String '登録用データ配列
Dim myInd As Integer 'カウンタ

'oo4o用のオブジェクト
Dim OO4OSession As Object
Dim EmpDb As Object
Dim sqlStatement As Object

'-----------------
' 初期処理
'-----------------

'INSERT文作成
mySql = ""
mySql = mySql & " INSERT INTO"
mySql = mySql & " TESTDB (TESTSTR,TESTNUM)"
mySql = mySql & " VALUES (:ADDSTR, :ADDNUM)"

'登録用のデータ作成
myTbl(0, 0) = "A": myTbl(0, 1) = 1
myTbl(1, 0) = "B": myTbl(1, 1) = 2
myTbl(2, 0) = "C": myTbl(2, 1) = 3

'-----------------
' DB接続
'-----------------

'更新用のDB接続
Set OO4OSession = CreateObject("OracleInProcServer.XOraSession")
Set EmpDb = OO4OSession.OpenDatabase(ORA_DBSTRING, ORA_USERNAME & "/" & ORA_PASSWD, 0&)

'バインド変数の設定
EmpDb.Parameters.Add "ADDSTR", CStr(myTbl(0, 0)), 1
EmpDb.Parameters("ADDSTR").ServerType = 1 'ORATYPE_VARCHAR2

EmpDb.Parameters.Add "ADDNUM", CInt(myTbl(0, 1)), 1
EmpDb.Parameters("ADDNUM").ServerType = 2 'ORATYPE_NUMBER

'-----------------
' データ登録
'-----------------

'トランザクションを開始します。
EmpDb.BeginTrans

'Insert文の実行(1件目)
Set sqlStatement = EmpDb.CreateSQL(mySql, &H2&)

'Insert文の実行(2件目以降)
For myInd = 1 To UBound(myTbl)

'バインド変数の再設定
EmpDb.Parameters("ADDSTR").Value = CStr(myTbl(myInd, 0))
EmpDb.Parameters("ADDNUM").Value = CInt(myTbl(myInd, 1))

'Insert文を実行
sqlStatement.Refresh

Next

'-----------------
' 終了処理
'-----------------
'正常終了
normalEnd:

'コミットします。
EmpDb.CommitTrans

'終了メッセージの表示
MsgBox "正常終了!" & Chr(10) & Chr(10) & "登録件数:" & sqlStatement.RecordCount

'オブジェクトの開放
Set sqlStatement = Nothing
Set EmpDb = Nothing
Set OO4OSession = Nothing

'終了
Exit Sub

'異常終了
systemError:

'エラーメッセージ表示てからエラーをクリア。
If Not Err.Number = 0 Then MsgBox (Err.Number & ", " & Err.Description)
Err.Clear

'エラートラップを無効にします。
On Error GoTo 0


'ロールバックします。
EmpDb.Rollback


'オブジェクトを開放します。
Set sqlStatement = Nothing
Set EmpDb = Nothing
Set OO4OSession = Nothing

End Sub


ソース説明

1. トランザクションの開始

トランザクションは、OraDatabaseオブジェクトのBeginTransメソッドを使用することで開始されます。
(OraSessionオブジェクト、OraConnectionオブジェクトでも使えます)

このメソッドを実行すると、その後の実行しているInsert文はコミットされるまでDBに反映されません。

2. トランザクションの終了(正常時)

コミットは、CommitTransメソッドで実行することが出来ます。
このメソッドを実行することで、発行したInsert文が確定されて、トランザクションが終了します。

3. トランザクションの終了(異常時)

処理が異常終了した場合、実行したInsert文をキャンセルするためにロールバックを実行します。
これは、Rollbackメソッドで実行します
このメソッドを実行することで、発行したInsert文が取り消されて、トランザクションが終了します。

ちなみに、エラートラップを「On Error GoTo systemError」で実現しているため、トランザクションの開始前(BeginTransメソッドの発効前)にエラー処理が実行されることがあります。

トランザクションが開始されていない状態でRollbackメソッドを実行するとエラーが発生することがあるので、直前に「On Error GoTo 0」でエラートラップを無効可しています。


考察

なんか、わかっている人のための記述になっちゃいましたね。
(まぁ、一種の備忘録なので、これはこれで良いんですが)

2年くらい前に、データベーススペシャリストを受験した時に、真剣に勉強したことがあるので、詳しく書けないこともないかも知れませんが、なんか理論に偏っちゃいそうなんですよね。

こんなブログで、教科書みたいなこと書いても面白くないので、サンプルだけにしときました。


おまけ

oo4oでのトランザクションの実行方法は、他にもあるので紹介しておきます。
もっとも、正攻法とは言えないのでお勧めしませんが...。

1. トランザクションの開始

OraDatabaseオブジェクトの、AutoCommitプロパティというのが、コミットのタイミングを制御しています。
これは、boolean型でTrueであれば、自動的にコミットされ、Falseであれば、トランザクション制御をしないとコミットされなくなります。

つまり、サンプル中の「EmpDb.BeginTrans」は「EmpDb.AutoCommit = False」に書き換えることが出来ます。

2. コミット

サンプルでは、CommitTransメソッドを使用していますが、SQLで直接コミットを実行しても問題なく動作します。
サンプルの「EmpDb.CommitTrans」は「EmpDb.ExecuteSQL ("commit")」に書き換えられます。

3. ロールバック

ロールバックも同様に、「EmpDb.Rollback」を「EmpDb.ExecuteSQL ("rollback")」に書き換え可能です。

4. その他

コミットとロールバックは、CreateSQLメソッドを使用してもokです。
コミットであれば、こんな感じです。


Dim sqlTran As Object
Set sqlTran = EmpDb.CreateSQL("commit", &H2&)


まぁ、戻値を受け取るオブジェクトが増えるので、あえて使う理由は思いつきませんが...


前回:oo4oでExcelから登録してみた(CreateSQL)
投稿記事の一覧:目次

--- blog end ---


スポンサードリンク

PageTop

コメント


管理者にだけ表示を許可する