データベース更新を確定させるCOMMIT WORK命令、データベース更新を取り消すROLLBACK WORK命令、それらの前提となるLUWやコミット・ロールバックの概念について解説します。
また、2つの命令の役割を整理するにあたり前提となる「LUW(作業論理単位)」の概念についても合わせて解説します。
SAPエンジニア・ABAPerを目指す方であれば知らないと恥ずかしい基本知識の1つです。是非最後までご覧ください。
LUW(作業論理単位)とは?
コミットとロールバックを理解するためには、LUW(作業論理単位)の理解が必須です。
LUW(作業論理単位)とはデータが1つの状態からまた別の状態に移る間のことを指します。
LUWは、これ以上分割することができないデータベース更新の単位。つまり、データベースは「変更前」の状態か「変更後」の状態のいずれかしか保持せず、例えばINSERT命令・DELETE命令等でレコードを追加・削除中にエラーが起きて中途半端にデータ更新が行われた ”中間状態” にはなりえないという概念です。
レコードのUPDATEに失敗したとしても、データベースが中途半端に更新されるという状態にはなりません。
失敗したら「変更前」に戻す、成功したら「変更後」の状態を確定させる。
大事なのは "中間状態" でレコードが保持されることは無い、という点です。
更新中にエラーが起きて、変更前の状態に戻すことを「ロールバック」。更新が成功して、変更を確定させることを「コミット」と言います。
SAPのコミットとロールバック
SAPではコミットとロールバックを明示的にABAP命令で行うパターン(明示的コミット/ロールバック)、システムによって自動で行われるパターン(暗黙的コミット/ロールバック)の2種類が存在します。
ここでは、コミットとロールバックには明示的/暗黙的の2つが存在するんだ、ということを頭に入れておけばOKです。
ページ後半までお読みいただければ、徐々にそれらの違いが分かっていくようになるはずです。
まずは、明示的コミット/暗黙的コミットについて整理していきます。
明示的コミット:COMMIT WORK命令
明示的にコミットを行う命令です。
COMMIT WORK (AND WAIT).
COMMIT WORK命令は、データベースへの更新を確定させます。以下のサンプルコードをご覧ください。
* テーブルY001をUPDATE UPDATE Y001 SET ZZ_NAME1 = <LDT_Y001>-ZZ_CD "ユーザコード" WHERE ZZ_CD = <LDT_Y001>-ZZ_CD. * 正常終了ならコミット IF SY-SUBRC = 0. COMMIT WORK. ENDIF.
UPDATE命令が成功した段階では、厳密に言うとデータベースには反映されておりません(コミットされていない)。
この未確定の更新依頼を確定し、データベースの値を事実として書き換える際にCOMMIT WORK命令を用います。
COMMIT WORK AND WAIT
COMMIT WORK命令の後に「AND WAIT」オプションをつけるとコミットが同期的に行われるようになります。
* テーブルY001をUPDATE UPDATE Y001 SET ZZ_NAME1 = <LDT_Y001>-ZZ_CD "ユーザコード" WHERE ZZ_CD = <LDT_Y001>-ZZ_CD. * 正常終了ならコミット IF SY-SUBRC = 0. COMMIT WORK AND WAIT. ENDIF.
COMMIT WORK命令を出した時点では厳密にはコミット処理までたどり着いていないということ。あくまでも、コミットしておいてね!というのをデータベースに伝えただけの状態がAND WAITなしのコミットです。
COMMIT WORK AND WAIT とオプション付与することによって、データベースにコミットされたことを確認するまで次の処理に進みません。
データベースの変更を前提としている処理が後続に控えている場合、AND WAITオプションを利用して確実にデータベースの更新を確定させる必要があります。
暗黙的コミット
COMMIT WORK命令を利用しなくても、以下のタイミングで暗黙的にコミットが走ります。基本的には、ワークプロセスが変更されたタイミングで発生すると理解すればOKです。
コミットされるタイミングを理解しておくことで、ロールバックができるタイミングがいつなのか?を適切に判断することができます。
ここからは、コミットの反対:ロールバックについて解説します。
明示的ロールバック:ROLLBACK WORK命令
ROLLBACK WORK.
COMMIT WORK命令の反対です。
* テーブルY001をUPDATE UPDATE Y001 SET ZZ_NAME1 = <LDT_Y001>-ZZ_CD "ユーザコード" WHERE ZZ_CD = <LDT_Y001>-ZZ_CD. * 正常終了ならコミット/異常終了ならロールバック IF SY-SUBRC = 0. COMMIT WORK AND WAIT. ELSE. ROLLBACK WORK. ENDIF.
UPDATE命令などが失敗したとしても、レコードに一部の更新が入ってしまっている場合などがあります。
その変更を確実に破棄し、UPDATE命令実行前の状態に戻したい場合は必ずROLLBACK WORK命令を実行します。
尚、再度の補足になりますがロールバックが行えるのはコミットされる前のタイミングのみです。
一度コミットされてしまったレコードをもとに戻すことはできませんので注意しましょう。明示的コミットをしていない場合でも、暗黙的にコミットが走っていれば、ROLLBACK WORKは効きません。ROLLBACK WORKが利用できるタイミングなのかどうかはコミットのタイミングをしっかり把握していないといけないということです。
暗黙的ロールバック
ロールバックも暗黙的に行われる場合があります。基本的には、何か予期せぬエラーが発生したタイミングだと理解すればOK。
これにて、LUWとコミット・ロールバックの基本理解はOKです。
SAP / ABAPを1から学習したい方は
初めてABAPを勉強するのは結構難しいですよね。
でもその悩みを抱えているのは一人じゃありません。全てのABAP使いが同じ道を進んできました。
ABAPをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?
読者料典 【完全無料】ABAP:学習カリキュラム ←こちらから!