データ更新時のトランザクション管理について

データベース
スポンサーリンク

久々の投稿です。

今回は「トランザクション管理」について紹介しようと思います。

はじめに

世の情シスさんのなかでは、MS Accessのマクロやアクションクエリなどを駆使して、ちょっとしたサブシステムを作っている人たちも多いかと思います。Accessのマクロやクエリを使ってフォームに処理を組み込むことは、VBAをあまり触らなくても作れることから、IT初心者から脱した情シスさんから絶大な支持を得ています。

例えば、フォームAに更新ボタンを設置し、そのボタンクリック時のマクロを登録し、そのマクロの処理として、更新クエリ1を呼ぶ、次に更新クエリ2を呼ぶ、次に更新クエリ3を呼び、メッセージボックスを出して処理の完了を通知する。といった感じです。

この様なマクロを実行する場合、マクロ内で実行される更新クエリ1から更新クエリ3までが、常に全て正常終了するのであれば問題はないのですが、状況によっては、更新対象データの異常などによって更新クエリのどれかで失敗することもあります。そうすると面倒なことになります。

トランザクション管理が必要なケース

上記のマクロの例で言えば、マクロを実行し、更新クエリ1が正常に終了し、更新クエリ2が失敗した場合ですが、更新クエリ1は正常に終了している為、更新ボタンを押下して再度マクロに組み込んだ処理を呼んでしまうと、再度更新クエリ1が実行されて不要なデータ更新がされてしまう可能性があります。その為、マクロを呼ぶのではなく、手動で更新クエリ2と更新クエリ3を個別に呼び出して実行する必要があります。

また、マクロではエラー処理も設定できる為、エラーが有っても無視する設定にしていた場合は、更新クエリ2のエラーではマクロは停止せず、その次の更新クエリ3も動いてしまいます。そうすると、更新クエリ3が、本来更新クエリ2で更新されたデータを対象とするクエリだった場合は更新クエリ2が失敗して更新されていないにも関わらず更新クエリ3が動くことで、意図しないデータに対して更新を掛けてしまう恐れがあります。一度更新してしまったデータは戻せませんから、状況によっては目も当てられない状態になる可能性があります。恐ろしいですね・・・。

上記の様な更新を連続で3回実行するような処理の場合、望ましい制御としては、
「全ての更新処理のうち、どれか一つでも失敗したら、その前に実行された更新処理を無かったことにしてデータを処理前の状態に戻す」
ということでしょう。

これを実現するのが「トランザクション管理」です。

トランザクション管理とは

トランザクション管理とは、業務システムなどにおける、データ更新を安全、確実に行う為の仕組みです。更新処理は成功か失敗かのどちらかしか許さず、その中間の「中途半端に更新」状態を発生させない仕組みです。難しい言葉で言えば「データベースのACID特性における原子性」です。

トランザクション管理の実装例

具体的には、プログラムのなかで、データ更新処理を実行する前に、以下のような記述をします。※VBScript + ADOの場合

BeginTrans

正確にはADOの Connectionオブジェクト名.BeginTrans という書き方です。

この一行を書いておくと、「これ以降の更新処理は、実行しても直後にデータへ反映はさせず、良いと言うまで待っててね。」という指示になります。

後は、更新処理結果をデータに反映させる処理と、更新処理に失敗した場合にそれまでの更新処理を取り消す処理を記述します。

更新処理結果をデータに反映させる処理は、最後の更新処理の記述の後ろの行に以下のように記述します。

CommitTrans

正確にはADOの Connectionオブジェクト名.CommitTrans という書き方です。この処理が実行されて初めてそれまで実行されたデータ更新の処理が実データに反映されます。

また、更新処理を無かったことにする処理は、エラー処理を用意して、そのなかで以下のように記述します。

RollbackTrans

こちらも正確には、ADOの Connectionオブジェクト名.RollbackTrans という書き方です。この処理が実行されると、それまで実行された更新処理を無かったことにして、データを更新前の状態に戻します。

今回のトランザクション管理を組み込んだサンプルプログラムの例としては、過去に掲載した以下のページを参考にしてください。※AccessやExcelなどのVBAのサンプルプログラムをいずれ掲載したいですね・・・

【VBScript】SQLServerに接続してSQL(UPDATE)を実行
SQLServerに接続し、UPDATE文のSQLを実行するサンプルコードです。 Option Explicit Call Main() Sub Main() Dim objCon Dim query ...

まとめ

今回のトランザクション処理は、データベースを扱うシステムを作るうえで、必ず必要な技術になります。また、例として挙げたAccessの場合は、マクロと更新クエリの組み合わせで処理を実装している場合は、トランザクション管理ができません。VBA+ADOで記述する必要があります。

マクロとクエリをベースにAccessシステムを作っている人の場合は、VBA+ADOは一気に難易度が上がる為、最初は大変かもしれませんが、習得することで、今回紹介したトランザクション管理も使えるようになり、より自身が構築したシステムの安定性や完成度が高まる為、強くおすすめします。是非活用してください。

↓併せて読んでもらうと良いかも

【SQL Server】ロック中の行にSELECTやUPDATEをする方法とロック管理入門
今回はSQL Server環境でトランザクションを掛けてロック中の行に対して、SELECTやUPDATEをするやり方を紹介します。 それにともなって、トランザクション管理やロックの必要性、トランザクション分離レベルについても解説します。 ...
タイトルとURLをコピーしました