COMMIT WORK / ROLLBACK WORK命令
21.2 COMMIT WORK / ROLLBACK WORK命令
2. COMMIT WORK / ROLLBACK WORK命令
ABAP における COMMIT命令とROLLBACK命令について見ていきましょう
前提知識として、
・データベース
・トランザクション
上記を知っておく必要があります。
データベースは「データを入れておく箱」です。
ABAPにおけるDBテーブルです。
トランザクションは「ここからここまでワンセット」な処理単位を指します。
ABAPにおいては、構造に格納されたデータをDBテーブルへ
INSERT 、UPDATE、 DELETE 命令で行う処理までが一つのトランザクション(一連の処理)です。
このトランザクションによって変更が加えられたDBテーブルの状態を確定する場合は、
・コミット
という処理が必要となります。
反対に、トランザクション(一連の処理)にて変更が加えられたDBテーブルの状態を
変更前に戻したい場合は、
・ロールバック
という処理が必要となります。
明示的/暗黙的について
ABAPでは前述のコミットとロールバックには、明示的にABAP命令で行うパターン
(明示的コミット/ロールバック)、システムによって自動で行われるパターン(暗黙的コミット/ロールバック)の2種類が存在します。
明示的コミット/暗黙的コミットについて
明示的にABAP命令で行うコミット命令
COMMIT WORK命令は、データベースへの更新を確定させます。
以下のサンプルコードをご覧ください。
REPORT ZTEST_PROGRAM_DBOP_INSERT. PARAMETERS: * 選択画面 S_NAME TYPE NAME OBLIGATORY. " 名前(※必須項目) DATA: WK_DB TYPE ZDBTBL_TEST_DBOP. START-OF-SELECTION. WK_DB-NAME = S_NAME. " 名前 INSERT INTO ZDBTBL_TEST_DBOP VALUES WK_DB. * 正常終了ならコミット IF SY-SUBRC = 0. COMMIT WORK. ENDIF. END-OF-SELECTION.
上記サンプルにおいて
INSERT命令が成功した時点では、データベースには反映されておりません(コミットされていない)が、この未確定の状態を確定し、データベースの値を事実として書き換える際にCOMMIT WORK命令を用います。
ただし、COMMIT WORK命令は、すぐにデータベースの値を確定するわけではなく、データベースにコミットを依頼し、どこかのタイミング(バックグラウンド)で値を確定します。そのため後続処理にてにデータベースが更新された値を使用する処理がある場合は、後述のAND WAIT を使用します。
COMMIT WORK AND WAIT
COMMIT WORK命令の後に「AND WAIT」オプションをつけるとコミットが同期的(コミットされるまで処理を待機)に行われるようになります。
サンプルコード
REPORT ZTEST_PROGRAM_DBOP_INSERT. PARAMETERS: * 選択画面 S_NAME TYPE NAME OBLIGATORY. " 名前(※必須項目) DATA: WK_DB TYPE ZDBTBL_TEST_DBOP. START-OF-SELECTION. WK_DB-NAME = S_NAME. " 名前 INSERT INTO ZDBTBL_TEST_DBOP VALUES WK_DB. * 正常終了ならコミット IF SY-SUBRC = 0. COMMIT WORK AND WAIT. ENDIF. END-OF-SELECTION.
前述でも述べましたが、データベースの変更を前提としている処理が後続に控えている場合、AND WAITオプションを利用して確実にデータベースの更新を確定させる必要があります。
補足
COMMIT WORKのリターンコード
SY-SUBRC
- 0・・・AND WAITオプションが指定されている&更新が正常終了
- 4・・・AND WAITオプションが指定されている&更新失敗
暗黙的コミット
COMMIT WORK命令を利用しなくても、以下のタイミングで暗黙的にコミットが走ります。
暗黙的コミットが発生するタイミング
・プログラムが終了したとき
・ダイアログステップが終了したとき
・MESSAGE命令が実行されたとき
(MESSAGE命令はダイアログステップを中断させるため)
明示的ロールバック:ROLLBACK WORK命令
REPORT ZTEST_PROGRAM_DBOP_INSERT. PARAMETERS: * 選択画面 S_NAME TYPE NAME OBLIGATORY. " 名前(※必須項目) DATA: WK_DB TYPE ZDBTBL_TEST_DBOP. START-OF-SELECTION. WK_DB-NAME = S_NAME. " 名前 INSERT INTO ZDBTBL_TEST_DBOP VALUES WK_DB. * 正常終了ならコミット IF SY-SUBRC = 0. COMMIT WORK AND WAIT. ELSE. ROLLBACK WORK. ENDIF. END-OF-SELECTION.
INSERT命令などが失敗したとしても、レコードに一部が入ってしまっている場合などがあります。
その変更を確実に破棄し、INSERT命令実行前の状態に戻したい場合は必ずROLLBACK WORK命令を実行します。
尚、再度の補足になりますがロールバックが行えるのはコミットされる前のタイミングのみです。
一度コミットされてしまったレコードをもとに戻すことはできませんので注意しましょう。
また、暗黙的にコミットがされていた場合も、ROLLBACK WORKは効きません。
ROLLBACK WORKが利用できるタイミングなのかどうかはコミットのタイミングをしっかり把握していないといけないということです。
暗黙的ロールバック
ロールバックも暗黙的に行われる場合があります。基本的には、何か予期せぬエラーが発生したタイミング(ショートダンプ等)
暗黙的ロールバックが発生するタイミング
・実行時エラー(ショートダンプ)が発生したとき
・プログラムが強制終了されたとき