◀ 2.

Oracle 19cのROLLBACK|SAVEPOINT・DDLの暗黙COMMITと製品別の違い

▶

ROLLBACKは、現在のトランザクションでまだコミットしていない変更を取り消すSQLです。Oracle Database 19cでは、全体を取り消すROLLBACKと、途中地点まで戻すROLLBACK TO SAVEPOINTを使い分けます。コミット済みの変更や外部APIの処理を巻き戻す命令ではありません。

この記事の要点
  • ROLLBACK は現在の同じ接続の未確定変更を取り消す。全体取消とSAVEPOINTへの取消は別
  • SAVEPOINT + ROLLBACK TO SAVEPOINT で部分ロールバックが可能
  • Oracle 19cの通常の永続表のDDLは暗黙COMMIT。MySQLとも境界を比較し、一時表の例外を区別
  • Oracleは暗黙開始。自動コミットは接続API・クライアント設定も確認し、Oracleの開始SQLにBEGINを付けない
  • Spring: @Transactional(rollbackFor = Exception.class) でチェック例外もロールバック対象に
  • Laravel: DB::beginTransaction() / DB::rollBack() または DB::transaction() クロージャ

Oracle 19cのSAVEPOINTとROLLBACK TO:後の変更だけ取消し、前の変更は未確定のまま残る

図は同一接続・自動コミットOFF・途中にDDLなしの模式図です。SAVEPOINTへ戻しても残りはまだ未確定であり、その後の全体ROLLBACKとCOMMITは別々の終了経路です。

OracleではBEGINを付けずに始める

Oracleのトランザクションは暗黙に始まります。BEGIN;やSTART TRANSACTION;を開始SQLとして実行しません。PL/SQLのBEGIN ... END;はブロックであり、独立したトランザクションの開始・終了を意味しません。Oracle 19c: Transactions

以下のOracle例は、同一接続で、クライアントの自動コミットを無効にし、トランザクションの途中にDDLを挟まない場合の説明です。Oracle・PostgreSQL・Spring・Laravelは資料との照合のみで、実行確認はしていません。後半のMySQLの自動コミット比較は、隔離したMySQL 8.4.13で確認した範囲を明示します。

自動コミットは接続APIやツールの設定も関係します。たとえばOracle JDBCの新しい接続は既定でauto-commitが有効です。「Oracleだから常にOFF」とは判断せず、実際の接続設定を確認します。Oracle 19c JDBC: Disabling Auto-Commit

ROLLBACK の基本

accounts(id, balance)がある練習用スキーマを想定した、取消を説明する例です。実際の送金処理としては不完全です。 送金元・先の存在、残高、更新件数、同時更新、再送などの確認は省略しています。UPDATEが0行でも自動でエラーになるわけではありません。

以前の比較例(保存用・実行しない)

旧例のBEGINはOracle用ではありません。Oracleは暗黙開始し、クライアントの自動コミットを無効にします。送金元・先、残高、更新件数、同時更新は別に検査します。ROLLBACK経路とCOMMIT経路は別の実行です。保存用であり、そのまま実行しません。

BEGIN;  -- または START TRANSACTION

UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;

-- 振込先口座が存在しないと判明
ROLLBACK;
-- → 上の 2 つの UPDATE は無かったことに

-- 正常時は COMMIT
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
-- Oracle 19c: 同じ接続で実行。クライアントの自動コミットは無効
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;

-- 例: アプリが送金先の更新件数0を検出した場合
ROLLBACK;

正常処理の確定は別の実行経路です。次を上のROLLBACKに続けて実行し直す指示ではありません。

-- Oracle 19c: 必要な業務チェックが成功した別の実行
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;

ROLLBACKはその接続の現在のトランザクションを終了し、変更を取り消してsavepointとトランザクションロックを解放します。DB全体や他人の変更を過去へ戻すものではありません。Oracle 19c: ROLLBACK

SAVEPOINT による部分ロールバック

次はorders / order_items / inventoryがある場合の境界説明です。必須列・制約・初期値は省略しています。在庫不足の判定や行ロックは別途必要です。SKU Aの注文をそのままSKU Cの在庫で処理することは、業務上正しい代替とは限りません。

以前の比較例(保存用・実行しない)

旧例のBEGINはOracle用ではありません。qty不足はこのUPDATEだけでは検出できず、SKU A/Bの明細を残してSKU Cだけ減らす代替も整合性を保証しません。ROLLBACK TO後の注文・明細は未確定です。保存用であり実行せず、直後の全体取消を含む訂正版を参照してください。

BEGIN;

INSERT INTO orders (id, customer_id) VALUES (1, 100);
SAVEPOINT after_order;

INSERT INTO order_items (order_id, sku) VALUES (1, 'A');
INSERT INTO order_items (order_id, sku) VALUES (1, 'B');
SAVEPOINT after_items;

UPDATE inventory SET qty = qty - 1 WHERE sku = 'A';
-- ★ qty が足りずビジネスルール違反と判明

ROLLBACK TO SAVEPOINT after_items;
-- → inventory UPDATE のみ取り消し。orders / order_items は残る

-- ここから別の在庫処理を試す
UPDATE inventory SET qty = qty - 1 WHERE sku = 'C';

COMMIT;
-- Oracle 19c: 自動コミット無効。DDLを混ぜない
INSERT INTO orders (id, customer_id) VALUES (1, 100);
SAVEPOINT after_order;

INSERT INTO order_items (order_id, sku) VALUES (1, 'A');
INSERT INTO order_items (order_id, sku) VALUES (1, 'B');
SAVEPOINT after_items;

UPDATE inventory SET qty = qty - 1 WHERE sku = 'A';
-- アプリが在庫処理の不成立を検出したと仮定
ROLLBACK TO SAVEPOINT after_items;
-- inventoryの更新を取消。注文/明細は未確定のまま残る。

-- 整合性のある代替処理がない場合は、注文/明細も全体取消
ROLLBACK;

代替処理を行うなら、在庫だけでなく注文・明細との整合性も確認し、成功時だけ最終COMMITします。ROLLBACK TO自体はトランザクションを終わらせず、指定savepointとそれ以前の地点を残し、それより後のsavepointを消します。同名のSAVEPOINTを再設定すると位置が変わります。Oracle 19c: SAVEPOINT、ROLLBACK TOの意味

Oracle 19cにはRELEASE SAVEPOINTというSQLはありません。MySQLやPostgreSQLの解放構文をOracleの例へ付け足さないでください。SAVEPOINTの詳しい記事にも比較例がありますが、製品名とトランザクション境界を確認します。

暗黙コミット (DDL)

Oracleは構文上正しいDDLの実行前にCOMMITし、成功したDDLの後にもCOMMITします。実行時エラーになったDDLでも、先行DMLの確定を防げるとは限りません。Oracle 19c: COMMIT

以下は通常の永続表へのDDLです。一時表には例外があり、transaction-specific private temporary tableの作成やprivate temporary tableのTRUNCATEは同じコミット規則ではありません。DDLの対象別注意で区別してください。

users(id,name)が存在し、logsがまだ存在しない、使い捨てスキーマで読む例です。クライアントが自動コミットしないことを前提にしています。

-- Oracle 19c
INSERT INTO users (id, name) VALUES (1, 'Alice');
CREATE TABLE logs (id NUMBER);
INSERT INTO logs (id) VALUES (1);
ROLLBACK;
-- 仕様上: Aliceとlogs表は残る。DDL後のlogsへのINSERTは取消。

この「最後のINSERTだけ取消」は、次のMySQL既定設定の例とは違います。DDLの基本と比較も参照してください。

AutoCommit と BEGIN

MySQLの新しい接続は通常autocommit=1です。明示トランザクションにはSTART TRANSACTION(またはBEGIN)を使えます。次の表は開始方法の比較であり、Oracleへ共通の開始文を付ける意味ではありません。MySQL 8.4: autocommit, Commit, Rollback

DBAutoCommit デフォルトトランザクション開始
MySQL 8.4 / InnoDB通常ON。接続設定を確認START TRANSACTION; または BEGIN;
PostgreSQL 18ON (psql)BEGIN;
Oracleクライアント次第。Oracle JDBCの新規接続はON。取消例では無効を確認暗黙的に開始
SQL ServerONBEGIN TRANSACTION;

比較表の出典: PostgreSQL 18 BEGIN、SQL Server BEGIN TRANSACTION。

MySQLではDDL後のINSERTも確定している場合がある

次は、autocommit=1を確認済みで、usersがInnoDB、logsが未作成の場合の例です。既存表へ実行しません。最後のINSERTだけ戻るという解釈は誤りです。 CREATE TABLEが明示トランザクションを終了させ、その後のINSERTはautocommitで確定します。MySQL 8.4: implicit commits

MySQLでの確認:MySQL Community Server 8.4.13 / InnoDBの使い捨て検体で、この条件の旧例を実行したところ、ROLLBACK後も別接続からAliceとlogsのid=1を各1件確認できました。後続の訂正例3本も元のSQLのまま実行し、DDL後に新しく開始したトランザクションの取消、autocommit=0との差、SAVEPOINT解放後の全体取消など計8ケースを確認しています。これはOracleや全DDLの挙動の実測ではありません。

以前の比較例(保存用・実行しない)

旧MySQL例の「INSERT (1)のみ取り消し」はautocommit=1では誤りです。CREATEが明示トランザクションを終了させ、後のINSERTも自動確定します。Alice・logs表・id=1が残ります。PostgreSQLは示した通常CREATEの比較に限定します。保存用であり実行せず、直後の訂正版を参照してください。

-- MySQL の例
BEGIN;
INSERT INTO users (name) VALUES ('Alice');
CREATE TABLE logs (id INT);   -- ★ ここで暗黙 COMMIT
INSERT INTO logs (id) VALUES (1);
ROLLBACK;
-- → logs テーブルは残る、INSERT (Alice) も残る、INSERT (1) のみ取り消し
-- ※ MySQL は DDL の Atomic 性が 8.0 で改善されたが、トランザクション境界は変わる

-- PostgreSQL は DDL もトランザクション可能
BEGIN;
CREATE TABLE logs (id INT);
ROLLBACK;
-- → logs テーブルは作られていない(PG の強み)
-- MySQL 8.4 / InnoDB: @@session.autocommit = 1
START TRANSACTION;
INSERT INTO users (name) VALUES ('Alice');
CREATE TABLE logs (id INT) ENGINE=InnoDB;
INSERT INTO logs (id) VALUES (1);
ROLLBACK;
-- 仕様上: Alice、logs表、logsのid=1はすべて残る。

DDL後のDMLだけを取り消す意図なら、DDLが成功した後に新しくSTART TRANSACTIONを置く必要があります。Aliceや表作成まで戻るわけではありません。

-- MySQL 8.4: logs表が存在する、別の実行経路
START TRANSACTION;
INSERT INTO logs (id) VALUES (2);
ROLLBACK;
-- このINSERTは取消対象。

autocommit=0を使う別方式もあります。次の例は、元がautocommit=1の専用接続で、既存の未確定処理がない場合に限定します。SET autocommit=1は未確定処理を確定することがあるため、接続プールで無条件に設定を上書きする手順にはしません。

以前の比較例(保存用・実行しない)

MySQL / InnoDBの旧例です。既存の未確定処理がない専用接続に限定します。SET autocommit=1は未確定処理を確定することがあり、接続プール設定へ無条件に転用しません。保存用であり実行しません。直後の条件付き比較を参照してください。

-- MySQL: AutoCommit を OFF に
SET autocommit = 0;

UPDATE users SET status = 'active' WHERE id = 1;
ROLLBACK;   -- 取り消し成功
-- 確認
SELECT status FROM users WHERE id = 1;  -- 元のまま

-- 元に戻す
SET autocommit = 1;
-- MySQL 8.4 / InnoDB: status列とid=1の行がある練習用表
SET autocommit = 0;
UPDATE users SET status = 'active' WHERE id = 1;
ROLLBACK;
SELECT status FROM users WHERE id = 1;
SET autocommit = 1;

atomic DDLは、対応DDLの1文を整合して完了・失敗させる仕組みであり、利用者がDDLを後からROLLBACKできる意味ではありません。MySQL 8.4: atomic DDL

比較: PostgreSQLのDDLとSAVEPOINTの解放

PostgreSQL 18では、次の通常のCREATE TABLEを明示トランザクションで取り消せます。すべてのDDLが対象ではなく、CREATE INDEX CONCURRENTLYなどはトランザクションブロック内で使えません。PostgreSQL 18: BEGIN、CREATE INDEX

-- PostgreSQL 18: logs表がまだない、別の練習用スキーマ
BEGIN;
CREATE TABLE logs (id INT);
ROLLBACK;
-- 仕様上: このCREATEでlogs表は残らない。

Nested Transaction (ネストトランザクション)

次はMySQL 8.4 / PostgreSQL 18のsavepoint構造の模式図です。省略部分はSQLではありません。RELEASE SAVEPOINTは戻る地点を解放するだけで、独立したCOMMITではありません。外側のROLLBACKなら内側で残した変更も取り消されます。MySQL 8.4 SAVEPOINT、PostgreSQL 18 RELEASE SAVEPOINT

以前の比較例(保存用・実行しない)

旧模式図のRELEASE SAVEPOINTは成功確定やCOMMITではなく地点の解放です。MySQL / PostgreSQL用でありOracleにはこのSQLはありません。外側のROLLBACKなら内側の変更も取消対象です。省略記号を含む保存用の図であり実行しません。

BEGIN;                       <- レベル 1
  ... 処理 ...
  SAVEPOINT sp1;             <- レベル 2 開始(ネスト風)
    ... 処理 ...
    SAVEPOINT sp2;           <- レベル 3
      ... 処理 ...
    RELEASE SAVEPOINT sp2;
  RELEASE SAVEPOINT sp1;
COMMIT;

* RELEASE SAVEPOINT は「成功確定」
* ROLLBACK TO SAVEPOINT で個別取消
* 最終的に外側で COMMIT しない限り全て一括コミット
開始 (MySQL: START TRANSACTION / PostgreSQL: BEGIN)
  外側のDML
  SAVEPOINT sp1
    内側のDML
    SAVEPOINT sp2
      内側のDML
    RELEASE SAVEPOINT sp2
  RELEASE SAVEPOINT sp1
COMMIT または全体ROLLBACK

Spring @Transactional でのロールバック

以下はSpring Frameworkの宣言的トランザクションの説明用断片です。サービスやリポジトリの実装、imports、transaction managerの設定は省略しています。同じ管理対象トランザクションへ参加するDB操作だけを対象にし、外部決済APIまで戻る保証にはしません。

以前の比較例(保存用・実行しない)

旧Spring例のREQUIRES_NEWは部分取消やsavepointではなく独立した物理トランザクションです。checked例外の既定ルールは明示/global設定で変わり、proxy自己呼出しは通常捕捉されません。決済APIまでDBと一緒に戻る保証はありません。省略記号・未定義実装がある保存用断片であり実行しません。

@Service
public class OrderService {

    @Transactional(rollbackFor = Exception.class)
    public void placeOrder(Order order) {
        orderRepo.save(order);
        inventoryService.reserve(order);  // ★ ここで例外が出ると...
        paymentService.charge(order);
        // → save も reserve も両方ロールバック
    }
}

// rollbackFor 指定の理由:
//   デフォルトでは RuntimeException / Error のみロールバック対象
//   checked Exception (IOException 等) はコミットされる
//   → rollbackFor = Exception.class で全例外を対象に

// 部分ロールバックには Propagation.REQUIRES_NEW でサブトランザクション化
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logFailure(String msg) { ... }

// アノテーション以外で明示ロールバック
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@Service
public class OrderService {
    @Transactional(rollbackFor = Exception.class)
    public void placeOrder(Order order) {
        orderRepo.save(order);
        inventoryService.reserve(order);
        paymentService.charge(order);
    }
}

通常の既定ルールはRuntimeException / Errorでロールバックし、checked exceptionではロールバックしません。rollbackForでルールを指定できます。ただしSpring 6.2以降はグローバル既定ルールも変更できるため、「checked exceptionは必ずコミット」とは言えません。既定のproxy方式では、同じインスタンス内の自己呼出しだけではアノテーションが適用されません。Spring: @Transactional

設定 仕組み 外側の処理との関係
REQUIRED 通常は外側の物理トランザクションへ参加 内側がrollback-onlyにすると外側COMMITがUnexpectedRollbackExceptionになる場合がある
NESTED 1つの物理トランザクション内のsavepoint 対応するJDBC transaction manager等が必要。外側ROLLBACKなら全体取消
REQUIRES_NEW 別の物理トランザクション 独立して確定・取消。内側COMMIT後は外側ROLLBACKでも戻らない

REQUIRES_NEWはsavepointによる「部分ロールバック」ではありません。別接続などの資源が必要になり、プール不足や待機も考慮します。Spring: transaction propagation

次の2つは異なる目的のメソッド断片です。呼出しをtransaction proxyが捕捉し、選択したmanagerとdriverが対応することが前提です。

// savepointに戻す内側処理。JDBC/managerの対応を確認する。
@Transactional(propagation = Propagation.NESTED)
public void reserveOptionalItem(Order order) { /* implementation omitted */ }

// 外側と独立して記録する処理。savepointとは別物。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logFailure(String msg) { /* implementation omitted */ }

プログラムからのTransactionAspectSupport.currentTransactionStatus().setRollbackOnly();も選択肢ですが、参加中のトランザクションをrollback-onlyにする操作であり、その場で一部分だけを取り消す命令ではありません。

Laravel でのロールバック

以下はLaravelの比較用断片で、Oracle接続の導入例ではありません。モデル、必須値、接続・driver・schemaは別途必要です。[...]は省略記号なのでそのまま実行できません。同じ接続のDB操作を想定し、外部APIやメールはDBと一緒には戻りません。

以前の比較例(保存用・実行しない)

旧Laravel例の3は追加3回ではなく初回込み最大3試行です。全Throwableを握りつぶして外側を確定するネスト例は安全な復旧手順ではありません。savepoint対応grammar/driverが必要で、モデル・必須値・[...]は未実装です。保存用であり実行せず、直後の訂正版を参照してください。

use Illuminate\Support\Facades\DB;

// パターン1: try / catch + 手動制御
DB::beginTransaction();
try {
    $order = Order::create([...]);
    OrderItem::insert([...]);
    DB::commit();
} catch (\Throwable $e) {
    DB::rollBack();
    throw $e;
}

// パターン2: クロージャ(推奨)
// 例外が出れば自動で rollBack、正常終了で commit
DB::transaction(function () {
    $order = Order::create([...]);
    OrderItem::insert([...]);
}, 3);  // ★ デッドロック時 3 回リトライ

// 手動 SAVEPOINT 風: ネスト transaction
DB::transaction(function () {
    DB::table('outer')->insert(['v' => 1]);

    try {
        DB::transaction(function () {
            DB::table('inner')->insert(['v' => 2]);
            throw new \Exception('rollback inner');
        });
    } catch (\Throwable $e) {
        // inner だけ rollBack。outer はそのまま COMMIT
    }
});
use Illuminate\Support\Facades\DB;

DB::beginTransaction();
try {
    $order = Order::create([...]);
    OrderItem::insert([...]);
    DB::commit();
} catch (\Throwable $e) {
    DB::rollBack();
    throw $e;
}

クロージャは正常終了時にcommitし、例外時にrollbackします。第2引数の3は初回を含む最大3試行です。再試行でクロージャ全体が再実行されるため、外部決済などの非冪等な副作用を安易に入れません。Laravel 13: database transactions

DB::transaction(function () {
    $order = Order::create([...]);
    OrderItem::insert([...]);
}, 3);

次はsavepoint対応driver / grammarで読むネスト比較です。outer / innerは説明用の表名で、実際のschemaに合わせる必要があります。RuntimeExceptionを内側だけで処理する例であり、接続障害・deadlock等を含むあらゆるThrowableを握りつぶして外側を確定する推奨ではありません。

DB::transaction(function () {
    DB::table('outer')->insert(['v' => 1]);
    try {
        DB::transaction(function () {
            DB::table('inner')->insert(['v' => 2]);
            throw new \RuntimeException('rollback inner');
        });
    } catch (\RuntimeException $e) {
        if ($e->getMessage() !== 'rollback inner') {
            throw $e;
        }
    }
});

これは独立トランザクションを2つコミットする例ではありません。内側のsavepointへの取消が成功して外側が正常終了すれば外側の行だけ残り、外側もrollbackすれば両方残りません。対応はframeworkだけでなくgrammar / PDO / driverでも確認します。Laravel 13の実装はsavepoint対応判定で分岐していますが、この組合せを実行検証したわけではありません。Laravel 13公式実装: ManagesTransactions

Distributed Transaction (XA)

XA / 2相コミットでは、prepare後の障害によって結果未確定(in-doubt)の状態が残ることがあります。commit段階のtimeoutを「全参加者が自動でROLLBACK」と読み替えません。Oracleの分散トランザクションにはRECOによる解決と管理手順があります。Oracle 19c: managing distributed transactions

以前の比較例(保存用・実行しない)

旧模式図の「通信障害ならタイムアウトでROLLBACK」は誤りです。prepare後はin-doubtになり得ます。XAの識別子とcoordinator判断をコピーして強制解決しません。製品採用やSagaの主流という主張も根拠にしません。保存用の非実行例です。

2 相コミット (2PC):
  Phase 1 (Prepare): すべての参加 RM に「準備できる?」と聞く
                     全員 OK → Phase 2 へ。1 つでも NG → 全員 ROLLBACK
  Phase 2 (Commit) : 全員 COMMIT
                     どこかで通信障害 → タイムアウトで ROLLBACK

実装:
  - JTA (Java Transaction API) / Atomikos / Bitronix
  - MySQL XA: XA START 'gtrid'; XA END 'gtrid'; XA PREPARE 'gtrid'; XA COMMIT 'gtrid';
  - マイクロサービスでは XA を避け、Saga パターンが主流
2PCの概念図(実行コマンドではない)
  Prepare: 各参加者が確定準備の結果を返す
  決定: coordinatorの決定に従ってcommit/rollbackを進める
  通信障害: 結果を確認できないことがある。timeoutだけで取消済みとしない

次はMySQL 8.4 XAの文の順序を読むための断片です。実際にはSTARTとENDの間に参加DB操作があり、coordinatorが結果を管理します。この並びを実行するだけで複数DBを安全に確定できるわけではありません。gtridも説明用識別子で、障害解決時にコピーして実行しません。MySQL 8.4: XA statements

XA START 'gtrid';
-- participating DML omitted
XA END 'gtrid';
XA PREPARE 'gtrid';
-- coordinator decision omitted
XA COMMIT 'gtrid';

JTAやtransaction coordinator、MySQL XAなどはこの問題を扱う別の層です。外部サービスを含めた補償処理も通常のDB ROLLBACKとは異なります。結果不明の処理を無条件に再実行したり、一般のROLLBACK記事だけで強制解決を行ったりしません。特定のcoordinator製品の新規採用や、Sagaが一律に適切という推奨はここでは行いません。

ROLLBACK が効かないケース

状況 確認すること
すでにCOMMIT・自動コミットされた 取消対象は現在の未確定変更だけ。復旧とは別問題
Oracle / MySQLで途中にDDLを挟んだ 暗黙COMMITの位置と、その後に開始したトランザクション
MySQLで非トランザクション表を使った engineごとの対応。混在表の全体取消を保証しない(MySQL公式の注意)
別接続の処理だった rollback対象の接続・transaction manager
決済・ファイル・メールなど DB外の作用。補償・冪等性・結果照合が別途必要
接続が切れた 切断前のCOMMIT応答の有無。通信エラーだけで取消成功とは断定しない

OracleではCOMMITが永続化された後に成功応答を受け取れない場合もあります。クライアントのエラーを「書込みなし」の証明にしません。Oracle 19c: COMMIT / WAIT

FAQ

TRUNCATEなら取消できますか? Oracle 19cではできず、FLASHBACK TABLEでも内容を戻せません。DELETEなら未確定変更を取り消せますが、コミットを分割すれば一括取消もできなくなります。DELETE ... LIMITはOracleの共通構文ではなく、バッチなら必ず安全という保証もありません。Oracle 19c TRUNCATE TABLE

プロシージャ内のROLLBACKは外側にも影響しますか? Oracleの通常のサブプログラムが呼出し元と同じトランザクションで実行している場合、単なるROLLBACKは呼出し元の未確定処理も含めます。savepointでの取消と、独立したautonomous transactionは別です。MySQLのHANDLERも、それだけで独立トランザクションを作るわけではありません。Oracle 19c Transactions: autonomous transactions

ROLLBACK後には領域整理が必要ですか? 行の変更取消と、表領域・データファイルの縮小は別です。ROLLBACKしたことだけを理由に、他製品のVACUUMやOPTIMIZE TABLE、索引再構築を追加する必要があるとは言えません。

次に、トランザクション制御の分類、DDLの暗黙COMMIT、SAVEPOINTを対比すると、どこまで取り消せるかを整理できます。

子ページ

子ページはありません

同階層のページ
  1. COMMIT (トランザクション制御)
  2. ROLLBACK
  3. SAVEPOINT

最近更新/作成されたページ