【VB6・VBAメモ】DAO(Data Access Object) :トランザクション

DAO(Data Access Object)のトランザクションの使い方についてメモしておきます。
データ保全のため、トランザクションは覚えておくと便利なので、できるだけ使うようにしたいですね。
DAOでトランザクションを使用する場合は、Workspaceを使用する必要があります。

以下には(私が)良く使うパターンのサンプルコードをメモしておきます。
(細かい説明はまた後日新しい記事を更新する、、、かもしれません)

【使用例】トランザクション
基本的なトランザクション開始からコミット、例外エラー時のロールバックの一連の流れのサンプルです。
なお、今回は省略せずに書いていますが、「DAO.」は省略可能です。
また、Workspaceはカレントに1つ自動で生成されるようなので、Workspaceを生成しなくても1つのトランザクションは動作できます。
Sub Sample1()
    Dim path As String
    Dim ws   As DAO.Workspace
    Dim db   As DAO.Database
On Error GoTo proc_err
    '-----------------------------'
    'DBパス'
    path = "D:¥Sample.mdb"
    'ワークスペース生成'
    Set ws = CreateWorkspace("", "Admin", "")
    'DBオープン'
    Set db = ws.OpenDatabase(path)
    
    'トランザクション開始'
    ws.BeginTrans
    
    
    'ここでDB編集'
    
    
    'コミット'
    ws.CommitTrans
    '-----------------------------'
    GoTo proc_end
proc_err:
    'ロールバック'
    ws.Rollback
proc_end:
    'DBクローズ'
    db.Close: Set db = Nothing
    'ワークスペース終了'
    ws.Close: Set ws = Nothing
End Sub

【検証】コミット
コミットを行った場合の流れを確認してみました。
コミット後に編集したレコードが確定しています。
Sub Sample2()
    Dim path As String
    Dim ws   As DAO.Workspace
    Dim db   As DAO.Database
    Dim rs   As DAO.Recordset
    '-----------------------------'
    'DBパス'
    path = "D:¥Sample.mdb"
    'ワークスペース生成'
    Set ws = CreateWorkspace("", "Admin", "")
    'DBオープン'
    Set db = ws.OpenDatabase(path)
    
    'トランザクション開始'
    ws.BeginTrans
    
    'レコードセットオープン'
    Set rs = db.OpenRecordset("SampleTable")
    'インデックスを指定'
    rs.Index = "PrimaryKey"
    
    '編集前のレコードを出力'
    Debug.Print "【編集前】"
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    
    'レコード追加'
    rs.AddNew
    rs!SampleCode = 500
    rs!SampleName = "レコード追加"
    rs.Update
    'レコード更新'
    rs.Seek "=", 2
    rs.Edit
    rs!SampleName = "レコード更新"
    rs.Update
    'レコード削除'
    rs.Seek "=", 3
    rs.Delete
    rs.Close: Set rs = Nothing
    
    '編集後のレコードを出力'
    Set rs = db.OpenRecordset("SampleTable")
    Debug.Print "【編集後】"
    rs.MoveFirst
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    
    'コミット'
    ws.CommitTrans
    
    'コミット後のレコードを出力'
    Set rs = db.OpenRecordset("SampleTable")
    Debug.Print "【コミット後】"
    rs.MoveFirst
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    '-----------------------------'
    'DBクローズ'
    db.Close: Set db = Nothing
    'ワークスペース終了'
    ws.Close: Set ws = Nothing
End Sub
【編集前】
 Code=100 Name=あいうえお
 Code=200 Name=かきくけこ
 Code=300 Name=さしすせそ
【編集後】
 Code=100 Name=あいうえお
 Code=200 Name=レコード更新
 Code=500 Name=レコード追加
【コミット後】
 Code=100 Name=あいうえお
 Code=200 Name=レコード更新
 Code=500 Name=レコード追加
【検証】ロールバック
ロールバックを行った場合の流れを確認してみました。
ロールバック後に編集したレコードが元に戻ります。

デバッグの時なんかはこんな感じで強制的にロールバックさせてみるのも便利です。
(リリース物に影響がないように気を付ける必要はありますが)
Sub Sample3()
    Dim path As String
    Dim ws   As DAO.Workspace
    Dim db   As DAO.Database
    Dim rs   As DAO.Recordset
    '-----------------------------'
    'DBパス'
    path = "D:¥Sample.mdb"
    'ワークスペース生成'
    Set ws = CreateWorkspace("", "Admin", "")
    'DBオープン'
    Set db = ws.OpenDatabase(path)
    
    'トランザクション開始'
    ws.BeginTrans
    
    'レコードセットオープン'
    Set rs = db.OpenRecordset("SampleTable")
    'インデックスを指定'
    rs.Index = "PrimaryKey"
    
    '編集前のレコードを出力'
    Debug.Print "【編集前】"
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    
    'レコード追加'
    rs.AddNew
    rs!SampleCode = 500
    rs!SampleName = "レコード追加"
    rs.Update
    'レコード更新'
    rs.Seek "=", 2
    rs.Edit
    rs!SampleName = "レコード更新"
    rs.Update
    'レコード削除'
    rs.Seek "=", 3
    rs.Delete
    rs.Close: Set rs = Nothing
    
    '編集後のレコードを出力'
    Set rs = db.OpenRecordset("SampleTable")
    Debug.Print "【編集後】"
    rs.MoveFirst
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    
    'ロールバック'
    ws.Rollback
    
    'ロールバック後のレコードを出力'
    Set rs = db.OpenRecordset("SampleTable")
    Debug.Print "【ロールバック後】"
    rs.MoveFirst
    Do Until rs.EOF
        Debug.Print "Code=" & rs!SampleCode & " Name=" & rs!SampleName
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    '-----------------------------'
    'DBクローズ'
    db.Close: Set db = Nothing
    'ワークスペース終了'
    ws.Close: Set ws = Nothing
End Sub
【編集前】
 Code=100 Name=あいうえお
 Code=200 Name=かきくけこ
 Code=300 Name=さしすせそ
【編集後】
 Code=100 Name=あいうえお
 Code=200 Name=レコード更新
 Code=500 Name=レコード追加
【ロールバック後】
 Code=100 Name=あいうえお
 Code=200 Name=かきくけこ
 Code=300 Name=さしすせそ


コメント
コメントする








    
この記事のトラックバックURL
トラックバック