トランザクション内のすべてのSQL文の処理が正常終了すればCOMMITを実行できますが,何らかの原因によってSQL文の一つでも正常終了しなかった場合,ROLLBACKを実行することによってそのトランザクションに含まれるすべての更新内容を更新前の状態に戻さなければなりません。

 今回の連載では「2007年11月20日に顧客番号1001の日経太郎さんに商品番号3000の商品を500円で販売した」という処理を一つのトランザクションとしています。このトランザクションには

 [SQL文1] 顧客テーブルを更新
 UPDATE 顧客テーブル SET 販売総額 = 販売総額+500 WHERE 顧客番号 = 1001;
 [SQL文2] 販売実績テーブルにレコードを1件挿入
 INSERT INTO 販売実績テーブル VALUES (‘20071120’,3000,1001,500);

という二つの更新処理が含まれています。仮にSQL文1は正常終了し,その後SQL文2が何らかの原因で異常終了したとすると,このトランザクションは成立しません。こうしたケースでは,このトランザクションを無かったものとしてROLLBACK処理の実行をRDBMSへ指示するのです。

 ROLLBACKの指示を受けたRDBMSは,データベースをそのトランザクションが始まる前の状態に戻します。この時,更新処理時に確保しておいた更新前データを使用します。SQL文2で追加したレコードは無効とし,SQL文1で更新されたレコードは更新前に戻します(図1)。これらの処理は,この時点では基本的に更新データをディスクに書き込んでいないため,メモリー・バッファ内での操作で済んでしまいます。

図1●ROLLBACK
図1●ROLLBACK

 また,ROLLBACKと同じような用語に「ROLLFOWARD」というものがあるのを聞いたことがあるかと思います。ここで少し,このROLLFOWARDについて説明したいと思います。

 ROLLBACKは,前述した通り確定しなかったトランザクションを無効にし,そのトランザクションが始まる前の状態にデータベースを戻すことです。アプリケーションから実行指示をすることによって行われることもあれば,何らかの原因でRDBMSが自動でROLLBACKを実行することもあります。

 一方のROLLFOWARDは,RDBMSが復旧する際に行う処理です。COMMITのところで説明した通り,トランザクションの確定時には,トランザクションログ・ファイルにのみその確定情報を書き込みます。よって,何らかの理由でRDBMSが異常終了し,メモリー・バッファ内のデータが消滅してしまうと,データベースは不整合な状態となってしまいます。

 このような状態でRDBMSが次にサービスを開始するとき,トランザクションログ・ファイル内の情報を基に,データベース・ファイル内のテーブル・データを更新して整合性を取ります。これが,ROLLFOWARDです(図2)。ROLLFOWARDはアプリケーションを開発する上ではあまり意識する必要の無いものですが,RDBMSが確定したトランザクションを保証し,常にデータベースの整合性を確保するために重要な機能の一つです。ぜひ覚えておきましょう。

図2●ROLLFOWARD
図2●ROLLFOWARD

藤塚 勤也(ふじづか きんや)
NTTデータ 基盤システム事業本部
オープンソース開発センタ 技術開発担当
シニアスペシャリスト
 沖電気工業,タンデムコンピューターズ(現日本HP)を経て,2003年より株式会社 NTTデータに勤務。現在は,オープンソース・ソフトウエアを活用したエンタープライズ・システム向けの技術開発・技術支援に従事しており,特にシステムの中核であるRDBMSに注力している。「RDBMS解剖学」(翔泳社)を共著