SAVEPOINT
Synopsis
SAVEPOINT pointname
引数
pointname | セーブポイントの名前。識別子として指定します。詳細は、"Caché SQL の使用法" の “識別子” の章を参照してください。 |
概要
SAVEPOINT 文は、トランザクション内のポイントを指定します。セーブポイントを設定することにより、セーブポイントにトランザクションをロールバックできます。ロールバックは実行されたすべての処理を取り消し、その期間に取得されたロックをすべて解放します。実行期間の長いトランザクション、または内部制御構造を持つトランザクションでは、トランザクションの間に送信されたすべての処理を取り消すのではなく、トランザクションの一部をロールバックできる方が便利な場合が多くあります。
セーブポイントを設定すると、$TLEVEL トランザクション・レベル・カウンタがインクリメントされます。セーブポイントまでロール・バックすると、$TLEVEL トランザクション・レベル・カウンタが、そのセーブポイントの直前の値にデクリメントされます。トランザクション内には最大 255 のセーブポイントを設定できます。このセーブポイントの数を超えると、SQLCODE -400 致命的エラーである SQL 実行中の <TRANSACTION LEVEL> 例外のキャッチが発生します。ターミナル・プロンプトには、現在のトランザクション・レベルがプレフィックスの接頭語の TLn: として表示されます。n は、現在の $TLEVEL のカウントを表す 1 ~ 255 の整数です。
各セーブポイントは、一意の識別子であるセーブポイント名に関連付けられています。また、セーブポイント名では大文字と小文字が区別されません。セーブポイント名は、区切り文字付き識別子とすることができます。
-
pointname を指定していない SAVEPOINT、または有効な識別子ではないか SQL 予約語である pointname を指定した SAVEPOINT を指定すると、ランタイム SQLCODE -301 エラーが発行されます。
-
“SYS” で始まる pointname を指定した SAVEPOINT を指定すると、ランタイム SQLCODE -302 エラーが発行されます。これらのセーブポイント名は予約されます。
セーブポイント名は、大文字小文字が区別されないので、resetpt、ResetPt、および "RESETPT" は同じ pointname です。この重複は、SAVEPOINT ではなく ROLLBACK TO SAVEPOINT の間に検出されます。重複する pointname を使用して SAVEPOINT 文を指定すると、Caché は、pointname が一意である場合と同様にトランザクション・レベル・カウンタをインクリメントさせます。ただし、最新の pointname がセーブポイント名のテーブル内のこれまでの重複する値をすべて上書きします。そのため、ROLLBACK TO SAVEPOINT pointname を指定すると、Caché はその pointname を持つ最後に設定された SAVEPOINT にロールバックし、トランザクション・レベル・カウンタを適切にデクリメントします。ただし、再度同じ名前で ROLLBACK TO SAVEPOINT pointname を指定すると、SQLCODE -375 エラーが生成され、%msg が "確立されていないセーブポイント 'name' に ROLLBACK できません" となり、完全トランザクションがロールバックされ、$TLEVEL カウントが 0 に戻ります。
セーブポイントの使用法
SAVEPOINT 文は、埋め込み SQL、動的 SQL、ODBC、および JDBC でサポートされます。JDBC は、connection.setSavepoint(pointname) はセーブポイントを設定し、connection.rollback(pointname) は指定されたセーブポイントにロールバックします。
セーブポイントを設定した場合 :
-
ROLLBACK TO SAVEPOINT pointname は、指定したセーブポイント以降に実行された処理をロールバックし、そのセーブポイントとすべての中間セーブポイントを削除して、削除したセーブポイント数分だけ $TLEVEL トランザクション・レベル・カウンタをデクリメントします。pointname が存在しないか既にロール・バックされている場合、このコマンドはトランザクション全体をロール・バックし、$TLEVEL を 0 にリセットして、すべてのロックを解除します。
-
ROLLBACK は、現在のトランザクションの間に実行されたすべての作業をロール・バックし、START TRANSACTION 以降処理された作業をロール・バックします。$TLEVEL トランザクション・レベル・カウンタを 0 にリセットし、すべてのロックを解除します。一般的な ROLLBACK は、セーブポイントを無視します。
-
COMMIT は、現在のトランザクションの間に実行されたすべての作業をコミットします。$TLEVEL トランザクション・レベル・カウンタを 0 にリセットし、すべてのロックを解除します。COMMIT はセーブポイントを無視することに注意してください。
トランザクション内で 2 番目の START TRANSACTION を発行しても、セーブポイントまたは $TLEVEL トランザクション・レベルのカウンタには影響を与えません。
トランザクションの動作が正常完了できなかった場合は、SQLCODE -400 エラーが発行されます。
例
次の埋め込み SQL の例では、2 つのセーブポイントを持つトランザクションを作成しています。
NEW SQLCODE,%ROWCOUNT,%ROWID
&sql(START TRANSACTION)
&sql(DELETE FROM Sample.Person WHERE Name=NULL)
IF SQLCODE=100 { WRITE !,"No null name records to delete" }
ELSEIF SQLCODE'=0 {&sql(ROLLBACK)}
ELSE {WRITE !,%ROWCOUNT," null name records deleted"}
&sql(SAVEPOINT svpt_age1)
&sql(DELETE FROM Sample.Person WHERE Age=NULL)
IF SQLCODE=100 { WRITE !,"No null age records to delete" }
ELSEIF SQLCODE'=0 {&sql(ROLLBACK TO SAVEPOINT svpt_age1)}
ELSE {WRITE !,%ROWCOUNT," null age records deleted"}
&sql(SAVEPOINT svpt_age2)
&sql(DELETE FROM Sample.Person WHERE Age>65)
IF SQLCODE=0 { &sql(COMMIT)}
ELSEIF SQLCODE=100 { &sql(COMMIT)}
ELSE {
&sql(ROLLBACK TO SAVEPOINT svpt_age2)
WRITE !,"retirement age deletes failed"
}
&sql(COMMIT)
&sql(COMMIT)
ObjectScript と SQL のトランザクション
TSTART と TCOMMIT を使用した ObjectScript トランザクション処理は、SQL 文 START TRANSACTION、SAVEPOINT、および COMMIT を使用した SQL トランザクション処理とは異なるもので、互換性もありません。ObjectScript および Caché SQL のいずれも、入れ子構造のトランザクションのサポートに制限があります。ObjectScript トランザクション処理は、SQL ロック制御変数 (特に SQL ロック・エスカレーション変数) と相互にやり取りしません。アプリケーションは、これら 2 種類のトランザクション処理を混同しないよう注意する必要があります。
トランザクションに SQL 更新文が含まれる場合、SQL の START TRANSACTION 文でトランザクションが開始され、COMMIT 文でコミットされます。トランザクションを開始するものでない限り、TSTART/TCOMMIT を入れ子にして使用するメソッドをトランザクションに組み込むことができます。メソッドとストアド・プロシージャは、通常、設計でトランザクションの主要なコントローラにならない限り、SQL トランザクション制御文を使用しません。
関連項目
-
SQL コマンド : COMMIT ROLLBACK SET TRANSACTION START TRANSACTION $TLEVEL
-
"Caché SQL の使用法" の “データベースの変更” の章にある "トランザクション処理"
-
"Caché エラー・リファレンス" にリストされた SQLCODE エラー・メッセージ
-
ObjectScript コマンド : TCOMMIT