Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

トランザクションとは?

DBMSに対して複数のSQL文を送る場合に、1つ以上のSQL文をひとつの単位として扱うように指示することができます。

このひとつの単位のことを「トランザクション」というのです。

具体的には、次のようなイメージになります。

SELECT 〜 FROM テーブル名;
↓
UPDATE テーブル名 〜;
↓
------------------ トランザクション ------------------ 
INSERT INTO テーブルアーカイブ 〜;
↓
DELETE テーブル名 〜;
------------------ トランザクション ------------------ 
↓
SELECT 〜 FROM テーブルアーカイブ;

上記の例でいくと、「INSERT INTO文」と「DELETE文」がトランザクションです。

トランザクションが必要な場面

データベースで起こり得るトラブルには、「予期しない処理中断」「同時操作」が考えられます。

これらのトラブルによって、DBMSが処理を正しく完了できなかったり、テーブル内のデータの値がおかしくなってしまう可能性もあるでしょう。

また、電気トラブルによって一連のSQL処理が途中で途切れてしまう可能性もあるのです。

トランザクションは、このようなトラブルを想定して「複数の処理を連続して行う場合に、すべての処理が成功した場合だけデータベースへの変更を有効にする」場合に必要になります。

そのため、もし電気トラブルがあってもトランザクションを利用していれば、途中までの処理内容は反映されず、不正な値が入ったりなどの不正が防げます。

トランザクション制御まとめ
  • トランザクションの途中で、処理が中断されないようにする
  • トランザクションの途中に、他の人が割り込めないようにする

トランザクションの特性について

トランザクションはその処理の特徴から「ACID特性」と言われる特性を満たす必要があります。

ACID特性とは、次の4つの特性の頭文字をとった言葉です。

  1. 原子性 (ATOMICITY)
  2. 一貫性 (CONSISTENCY)
  3. 隔離性 (ISOLATION)
  4. 持続性 (DURABILITY)

それぞれの特性について解説します。

原子性 (ATOMICITY)

原子生とは、それ以上分割ができない「最小の作業単位」であることを意味する特性です。

もう少し具体的に説明をすると、トランザクションを構成している処理の結果がすべて「有効」になるか、「無効」になるかのどちらかだけになります。

先ほどの例で例えると、「INSERT INTO文」と「DELETE文」の両方の処理が完了するか、しないかです。

------------------ トランザクション ------------------
INSERT INTO テーブルアーカイブ 〜;
↓
DELETE テーブル名 〜;
------------------ トランザクション ------------------

「INSERT INTO文」だけ処理が完了し、「DELETE文」だけはできなかった、ということはありえないというわけですね。

一貫性 (CONSISTENCY)

一貫性は、その名前の通り、データの内容が一貫していることを表す特性です。

トランザクションで処理したデータが、実行前と実行後で整合性がとれている状態になっていなくてはいけません。

こちらも先ほどの例で言えば、「INSERT INTO文」でデータを挿入後、「DELETE文」を実行しているため、トランザクション完了後はテーブル内のデータが削除された状態が、生合成がとれている状態です。

それなのに、「INSERT INTO文」で挿入したデータが残っている状態などになっていると、一貫性が保たれていないということになります。

このような状態は、当然ながら起ってしまうと問題になるので、トランザクションの特性としてあげられるのです。

隔離性 (ISOLATION)

隔離性は、複数のトランザクションの処理対象がある1つのデータの場合に、それぞれのトランザクションは隔離された状態でデータの更新を行うという特性です。

例えば、次のようなトランザクションがあるとしましょう。

・トランザクション1:「INSERT INTO文」と「DELETE文」を実行
・トランザクション2:「SELECT FROM文」と「UPDATE文」を実行

これらのトランザクションが同じデータに対して実行される時、トランザクション1を実行している途中で、トランザクション2を実行することは認められないということになります。

つまり、必ず「トランザクション1→トランザクション2」の順番か「トランザクション2→トランザクション1」の順番で処理が実行されることになります。

当たり前ですが、同時に処理を実行しようとした場合、予期せぬ動作やエラーが発生する原因になるため、このような特性を採用しているのです。

持続性 (DURABILITY)

持続性は、その名前の通りトランザクションで処理するデータは、トランザクションの処理が終わるまで変わらない状態を意味する特性です。

トランザクションの実行中に、処理するデータが変わってしまっては不具合やバグを生み出すことにつながります。

そのため、トランザクションが終了するまで、データの状態は変わりません。

トランザクションの書き方

トランザクションを実行するにはどのように記述すればよいですか?

トランザクションを使うためには「BEGIN」「COMMIT」「ROLLBACK」の記述が必要です。サンプルを見ながら書き方を学びましょう!

トランザクションを指定するには、「複数のSQL文のどの範囲が1つのトランザクションであるか」を明示することでDBMSが制御してくれます。

具体的には、次の3つのSQL文を使います。

SQL文 詳細
BEGIN トランザクション開始の指示です。
BEGIN以降に書かれたSQL文を、1つのトランザクションとします。
COMMIT トランザクション終了の指示です。
COMMIT以前に書かれたSQL文を、1つのトランザクションとし、変更を確定します。
ROLLBACK トランザクション終了の指示です。
ROLLBACK以前に書かれたSQL文を、1つのトランザクションとし、変更の取り消しをします。

トランザクション開始の指示は「BEGIN」だけですが、終了の仕方には「COMMIT」と「ROLLBACK」があるので覚えておきましょう。

例えば、従業員のデータを扱う 従業員テーブル の2020年8月以前のデータをバックアップテーブルに移動させる、といった処理をトランザクションで行ってみます。

SQL文は次のように記述しましょう。

BEGIN;
-- バックアップテーブルにコピー
INSERT INTO 従業員バックアップ
SELECT * FROM 従業員テーブル WHERE 日付 <= ‘2020-08-31’;
-- 従業員テーブルからデリート
DELETE FROM 従業員テーブル WHERE 日付 <= ‘2020-08-31’;
COMMIT;

上記のSQLを実行することで、「バックアップテーブルにコピー」と「従業員テーブルからデリート」は不可分なものとして扱われます。

万が一、バックアップテーブルにコピーした後にトラブルが発生しても、自動的にロールバックが行われて、「バックアップテーブルにコピー」は取り消されます。

また、 ROLLBACK のSQL文を実行することで、明示的にロールバックを行うことも可能です。

自動コミットモード

各DBMS付属のSQL実行ツールを使用している場合、ロールバックができないことがあります。

これは、多くのSQL実行ツールが「自動コミットモード」と呼ばれるモードをデフォルトで設定しているからです。

このモードが設定されていると、DBMSは1つのSQL文が実行されるたびに、裏側で自動的にコミットを実行してしまいます。

そのため、トランザクションをロールバックできない状況が生まれるのです。

DBMSによっては、自動コミットモード中であっても「BEGIN」を実行すれば、コミットかロールバックのまでの間は一時的に自動コミットを解除できます。

この自動コミットモードを解除する方法は、ツールや環境によって異なるので確認が必要です。

例えば、MySQLであれば「SET AUTOCOMMIT=0」というSQL文になります。

トランザクションの分離

DBMSに対して、複数の利用者が同時に処理を実行すると発生し得る副作用には次の3つが挙げられます。

副作用 詳細
ダーティーリード まだコミットしていない変更を他の人が読めてしまうという現象です。
未確定の情報・データをもとに処理を行ってしまう可能性があるので、とても危険な副作用と言えます。
反復不能読み取り あるテーブルに対してSELECT文を実行した後、他の人がUPDATE文でデータを書き換えた場合、次にSELECT文を実行した際に検索結果が異なるものになってしまう副作用です。
データの整合性が崩れてしまう原因になります。
ファントムリード 2回目のSELECT文を実行する間に、他の人がINSERT INTO文でデータを追加すると、検索結果が異なるものになってしまう副作用です。
反復不能読み取りと同じ理由で危険な副作用と言えます。

このようにDBMSの扱いは、複数人で行うほどデータの整合性を保つことが難しく、情報の錯綜につながりかねません。

上記の副作用を解決するためにも、トランザクションは有効な手段です。

なぜなら、DBMSはそれぞれのトランザクションについて分離性を維持しているからです。

3つの副作用のような影響を受けないために、トランザクションを実行する際は分離して実行します。

仮に、トランザクション1とトランザクション2を同時に実行していても、単独で実行しているのと同じ結果となるように制御しているのです。

まとめ

SQLのトランザクションについて解説しました。

データを正しく、安全に扱うためにトランザクションの利用は有効です。

特に、複数人で利用することが想定される場合は、積極的に活用を検討してみるとよいでしょう。

ぜひこの記事を参考に、トランザクションの理解を深めてください!

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。