7.1 トランザクション処理
今までの学習では、処理をひとつひとつ実行してきましたが、アプリケーションを開発していく中では、複数の処理を大きな一つの処理として扱いたいケースが出てきます。そのような場合には、トランザクションと呼ばれる処理を利用します。本節では、トランザクション処理について学習していきます。
7.1.1 トランザクション処理の概念
前述したように、トランザクション処理とは複数の処理を大きな1つの処理として扱うことです。もし、大きな処理の中で何らかのトラブルが発生した場合には、処理自体を取り消すことが可能です。
例えば注文処理を考えてみましょう。ユーザーが商品Aを注文したとします。この場合、注文テーブルに注文データを登録すると同時に、在庫データから商品Aの在庫をマイナス1する必要があります。ここでトランザクション処理を行わず、ひとつひとつの処理を実行した場合、問題が発生する可能性があります。
例えば注文テーブルにデータを登録し、在庫テーブルから在庫をマイナスする前に何らかのトラブルが発生してプログラムが終了してしまったとします。すると、この場合は注文テーブルと在庫テーブルに不整合が発生してしまうことになります。
図 7.1.1トラブルによるデータの不整合
このような場合は、処理①で行った注文テーブルへのデータ追加を仮登録の状態にしておき、トラブルが発生した場合、処理①で行った処理を取り消す必要があります。データを処理の前の状態に戻すことで、処理①自体をなかったことにする(取り消す)ことをデータベースの世界ではロールバック(ROLLBACK)すると言います。
図 7.1.2ロールバック
一方、何もトラブルが発生しなかった場合、処理①と処理②で行ったデータ操作は仮登録の段階ですので、仮登録の状態を確定させなければなりません。このように、処理を確定することを、コミット(COMMIT)と言います。
図 7.1.3コミット
7.1.2 トランザクション処理の準備
MariaDBでは、トランザクション処理を行う場合、トランザクション処理を行うことが可能な「ストレージエンジン」を指定する必要があります。ストレージエンジンとは、SQLのデータがどのような形式で、どのように格納されているかを管理している部分で、データベース管理システム (DBMS)がデータベースにアクセスするために使用するソフトウェアです。
MariaDBでは以下の2つが代表的なものとなっています。
① MyISAM(マイアイサム)
- テーブル単位のファイルによるデータ構造を持つ
- トランザクション機能がない分、軽快に動作する
- テーブル単位でロックがかかる
- 検索系の処理が多いアプリケーションの場合に有効
② InnoDB(イノディービィー)
- テーブルスペース内に複数のテーブルやインデックスを格納するデータ構造を持つ
- トランザクション機能をサポートしている
- 行(レコード)単位でロックがかかる
- 更新系の処理が多いアプリケーションの場合に有効
トランザクション処理を行う場合、ストレージエンジンが「InnoDB」でなくてはなりません。
MariaDBの場合は、デフォルトで「InnoDB」が設定されていますが、「MyISAM」になっている場合は、変更する操作が必要になります。
まずは、対象のテーブルのストレージエンジンを確認してみましょう。テーブルごとのストレージエンジンの情報は「information_schema」データベース内に存在します。今まで使っていた「bookinfo」について調べる場合は、以下のコマンドを実行して下さい。
図 7.1.4 :「bookinfo」テーブルのエンジンの確認
engine列に表示されているストレージエンジンの種類が「InnoDB」であれば後続の変更操作は必要ありませんが、図7.1.4のように現在のストレージエンジンが「MyISAM」になっていた場合は、このままではトランザクション処理を行うことができません。
この場合は、トランザクション処理を行うためのテーブルであることを明示して、「bookinfo」テーブルを作成し直す必要があります。
作成し直す時は、再度「mybookdb」データベースを選択し「DROP TABLE」コマンドを利用して「bookinfo」テーブルを削除します。
テーブルの削除が完了したら次のコマンドでテーブルを再作成して下さい。
トランザクション処理を行うことを明示して作成するには「CREATE TABLE」コマンドに、「ENGINE = InnoDB」オブションを付けます。「ENGINE」はストレージエンジンの選択に利用されるキーワードで、省略した場合は、MariaDBのバージョンに応じて、デフォルトで設定されているストレージエンジンでテーブルが作成されます。
図 7.1.5 :「InnoDB」を利用したテーブルの作成
テーブルの再作成が完了したらデータも再登録して下さい。
データの登録が完了したら、再度テーブルのストレージエンジンの確認を行なってみましょう。
図 7.1.6 :「ENGINE=InnoDB」をつけて作成した「bookinfo」テーブルのエンジンの確認
ストレージエンジンが「InnoDB」になっていることが確認できます。
これでトランザクション処理を行うための準備が完了になります。
7.1.3 トランザクション処理の実行
トランザクション処理を開始するには「BEGIN」コマンド、ロールバックするには「ROLLBACK」コマンド、コミットするには「COMMIT」コマンドを実行します。
トランザクション処理の流れは以下のようになります。
①トランザクション開始(BEGINコマンドの実行)
②処理の実行
③コミット(COMMITコマンドの実行)、またはロールバック(ROLLBACKコマンドの実行)
では実際にトランザクション処理を実行してみましょう。はじめに、データを追加した後に、取り消す処理(ロールバック)を行います。
それでは、再度「mybookdb」データベースを選択し、以下のデータを「bookinfo」テーブルに追加して下さい。
表 7.1.1 :ロールバック用データ
トランザクション処理を行う前に、現在のテーブルのデータを確認しておきます。
図 7.1.7 :「bookinfo」テーブル内のデータ
データの確認が完了したところで、実際にトランザクション処理を開始します。
図 7.1.8 :トランザクション開始及びデータの登録
この状態で、テーブルのデータを確認すると下図のようなデータになっています。
図 7.1.9 :テーブルに登録したデータの確認
では次に、データ登録処理の取り消し(ロールバック)を行い、もう一度テーブルのデータを確認してみましょう。
図 7.1.10 :登録処理の取り消しと確認
ROLLBACKコマンドが実行され、登録処理が取り消されているのがわかります。
今度は、テーブルのデータを一度全て削除し、これを取り消してみましょう。
まずは、データを全て削除し、データが1件もないことを確認します。
図 7.1.11 :削除処理とデータの確認
SELECTコマンドを実行した際に表示される「Empty set」はデータがないことを示しています。
では次に、削除処理を取り消し、データを確認してみましょう。次のコマンドを実行して下さい。
図 7.1.12削除処理の取り消しと確認
一度削除されたデータが元に戻っています。 このように、「ROLLBACK」コマンドを利用することで、トランザクション処理を開始する前のデータへ戻すことが可能です。 それでは今度は、処理を確定してみましょう。次のコマンドを実行して下さい。
図 7.1.13コミット処理の確認
「COMMIT」コマンドを実行することでトランザクション処理の内容が確定します。 この状態で「ROLLBACK」コマンドを実行しデータを確認してみましょう。
図 7.1.14コミット後のロールバックとデータの確認
今度は処理が確定されているため、新しく登録されたデータが残っていることが確認できます。