トランザクションとは
複数のSQL文をひとまとまりの作業単位として扱い、データの整合性を管理する仕組み。
エラーが起こった際にデータの一貫性を確保するだけでなく、OSやOracleインスタンスが異常停止した場合のデータベース整合性の回復(インスタンスリカバリ)や、データベースを構成するファイルが破損した際の復旧(メディアリカバリ)にも関わる仕組みである。
トランザクションの特性(ACID特性)
トランザクションは以下の4つのACID特性を持つ。
① 原子性(Atomicity)
ALL-OR-NOTHING 特性。一連の変更処理を1つのまとまりとして扱い、すべて実行されるか、まったく実行されないかのいずれかであることを保証する。
SQL では COMMIT / ROLLBACK によって実現される。
② 一貫性(Consistency)
トランザクション実行前にデータの整合性が保たれている状態であれば、実行後もその整合性が維持されるという特性。
制約(NOT NULL・主キーなど)によるデータ整合性の保証だけでなく、アプリケーション側でも一貫性を実現する設計が必要である。
③ 独立性・隔離性(Isolation)
同時に実行されたトランザクション同士が互いに干渉しないという特性。
Oracle はデフォルトの分離レベル READ COMMITTED(他のトランザクションがコミットした変更のみ読み取る)と、SERIALIZABLE の2段階の分離レベルを提供する。
④ 持続性・耐久性(Durability)
コミットされたトランザクションの変更が適切に保存され、障害が起きても失われないという特性。
Oracle では REDOログ(変更履歴)やアーカイブログによって持続性を実現し、インスタンスリカバリやメディアリカバリ機能で保証する。
トランザクションの実行
COMMIT
変更処理を確定する。コミット後は取り消せない。
コミットすると、そのトランザクションで定義していたすべてのセーブポイントが無効になる。
ROLLBACK
COMMIT を実行する前の変更処理を取り消す。
セーブポイント名を指定した ROLLBACK TO SAVEPOINT では、指定したセーブポイント以降の変更のみを取り消し、トランザクションは終了しない。
トランザクションの開始と終了
Oracle では変更処理を実行すると自動的にトランザクションが開始される。
トランザクションが開始されるタイミング
- トランザクションが実行されていない状態で DML 文を実行したとき
-
SELECT ... FOR UPDATEを実行したとき -
SET TRANSACTION文によって明示的に開始されたとき
トランザクションが終了するタイミング
| 終了の契機 | 処理の確定 |
|---|---|
COMMIT を実行 |
確定(コミット) |
| 接続を正常終了 | 確定(コミット) |
| DDL 文を実行 | DDL実行前後に暗黙的コミットが発生 |
ROLLBACK を実行 |
取り消し(ロールバック) |
| 接続が異常終了(Oracle 障害・SHUTDOWN など) | 自動的にロールバック |
【試験ポイント】DDL の暗黙的コミット
CREATE・ALTER・DROPなどの DDL 文は実行前後に暗黙的なコミットを発生させる。DDL 実行直前のコミットされていない DML 変更も自動的に確定される。
セーブポイント(SAVEPOINT)
トランザクション実行中の特定時点に「戻り先」のマークを付け、部分的なロールバックを可能にする機能。
使用方法
-- ① トランザクションを開始し、変更処理を実行する
-- ② セーブポイントを定義する
SAVEPOINT <セーブポイント名>;
-- ③ 定義したセーブポイントに戻りたい場合
ROLLBACK TO [SAVEPOINT] <セーブポイント名>;
-- ④ トランザクションを続けてCOMMITで確定する
COMMIT;
セーブポイントの注意点
- 複数のセーブポイントを指定できる
- 同名のセーブポイントを再定義すると、古いセーブポイントが上書き(消去)される。ROLLBACK TO 実行時は最新のセーブポイントが使われる
-
ROLLBACK TO SAVEPOINTはトランザクションを終了しない。トランザクションは COMMIT または ROLLBACK(全体)まで継続する -
COMMIT 後はセーブポイントがすべて無効になり、
ROLLBACK TO SAVEPOINTは使えなくなる
読取り一貫性
文レベルの読取り一貫性(デフォルト)
Oracle は SELECT と DML トランザクションが並行して実行された場合、SELECT 文の実行結果は「その SELECT 文の実行開始時点のデータ」を返す。
並行して別のトランザクションで変更・コミットされたデータは、進行中の SELECT 結果には反映されない(UNDO データを利用して実現)。
より高い一貫性を実現する方法
① SELECT ... FOR UPDATE
読取り対象の行に排他ロックをかけ、他のセッションがその行を変更できないようにする。
② 読取り専用トランザクション(READ ONLY)
SET TRANSACTION READ ONLY;
- トランザクション開始時点のデータのみを読み取るトランザクションレベルの一貫性を提供する
- そのトランザクション内では INSERT・UPDATE・DELETE を実行できない
- 複数の SELECT を実行した際に、一貫した時点のデータを参照し続けられる(レポート作成などに有効)
③ シリアライズ可能トランザクション(SERIALIZABLE)
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
- ANSI SQL 標準で定義された最も厳密な分離レベル
- トランザクション開始時点でコミットされていたデータのみを参照する(READ ONLY に近い一貫性)
- READ ONLY と異なり、DML(INSERT・UPDATE・DELETE)の実行が許可される
- ただし、シリアライズ可能トランザクション開始時点で他のトランザクションが変更中のリソースを DML で更新しようとすると、そのDML文はエラーとなる
【READ ONLY と SERIALIZABLE の比較】
| READ ONLY | SERIALIZABLE | |
|---|---|---|
| 一貫性の範囲 | トランザクション開始時点 | トランザクション開始時点 |
| DML の実行 | 不可 | 可 |
| SQL 標準 | Oracle 独自 | ANSI/ISO SQL 標準準拠 |
| 用途 | 読み取りのみのレポート | 一貫性が必要だが更新も行う処理 |
【試験ポイント】
同一トランザクション内で「文レベル」と「トランザクションレベル」の読取り一貫性を切り替えることはできない。
SET TRANSACTION文はトランザクションの最初の文として実行する必要がある。
変更前データの保管(UNDO)
Oracle では DML による変更が実行された場合、変更前のデータを UNDO データとして UNDO 表領域 に保管する。
UNDO の主な用途
| 用途 | 説明 |
|---|---|
| ① トランザクションのロールバック | 実行中のトランザクションを中断した際に、変更前の状態に戻す |
| ② 読取り一貫性 | 問合せ開始後に別セッションが変更したデータを隠蔽し、整合性のあるデータを返す |
| ③ インスタンスリカバリでのロールバック処理 | インスタンス異常終了時にコミット済みでないトランザクションをロールバックする |
| ④ フラッシュバック機能 | 過去のデータの参照や復元を行う |
フラッシュバック機能の種類
- フラッシュバック問合せ:過去の時点のデータを問い合わせる
- フラッシュバック表:表のデータを過去のある時点の状態に戻す
- フラッシュバックトランザクション問合せ:過去に実行されたトランザクション情報を確認する