どうもこんにちは!
サバ缶(@tech_begin)です。
データベースについて学習していると、必ずといっていいほど目にする「トランザクション」という言葉。
イマイチ分からないから……と読み飛ばしていませんか?
意外と簡単な仕組みなので、ぜひこの機会に学んでおきましょう💪
トランザクションとは
データベース管理システム(DBMS)には、正確なデータ操作を保証するため「トランザクション」という機能が搭載されています。
トランザクションとは「1つ以上のSQL文を1つのまとまりにした処理単位」のことです。
なぜトランザクションを使うのか
トランザクションを使って、一連の処理をまとめることでデータの整合性を保証することができます。
データベースの操作には、主に4種類あります。
この4種類の操作は『CRUD(クラッド)』と呼ばれます。
例えば、以下のような一連の複数のデータ処理を実行するとします。
- INSERT(ユーザテーブル)
- UPDATE(お知らせテーブル)
- UPDATE(お知らせ配信情報テーブル)
(ちなみに、スマホアプリの利用者に関するデータ操作を想定しています)
これらの実行途中に中断されてしまうと困る場面があります。
例えば、1つ目のユーザテーブルへのINSERT処理が成功し、2つ目のお知らせテーブルへのUPDATE処理が失敗したとします。
すると、ユーザテーブルにのみデータが生成され、お知らせテーブルには何も処理がなされていないということになります。
データの整合性(完全性)に欠けている状況になってしまいます。
銀行口座の処理で例える
もっとイメージしやすいように、銀行口座のお金の移り変わりで例えましょう。
- 山田さんがAmazonで1,000円の買い物をしました。
ここでは以下のような処理が実行されます。- 山田さんの口座から1,000円差し引く
- Amazonの口座に1,000円増やす
ここで「山田さんの口座から1,000円差し引く処理」のみ成功し、「Amazonの口座に1,000円増やす処理」失敗した場合どうなるでしょうか。
私はきちんと1,000円支払いましたよ!
いえ、こちらには振り込み記録がないです。。。
このように途中で処理に失敗したり中断されてしまうと大変なことになります。
トランザクションを使うことで、一連の処理を一括りにしてくれ、データの整合性を保証してくれるわけです。
SQL文で実際に書いてみる
SQLでトランザクションを使うとき、以下のような構成になっています。
トランザクション開始;
SQL;
SQL;
...
トランザクション終了;
複数のSQL文をトランザクション開始・終了文言で囲うことで実現可能です。
以降では、トランザクション開始・終了の書き方について見ていきます。
トランザクション開始
トランザクションの開始には、以下のどちらかのクエリを使用します。
- BEGIN
- START TRANSACTION
「BEGIN」と「START TRANSACTION」の違い
MySQLでは、「START TRANSACTION」が一般的のトランザクション開始ステートメントで、「BEGIN」はストアドプログラム(ストアドファンクション)を作成する際に使用します。
通常、UPDATEクエリなどを実行すると、毎回自動でコミットされます。(しかしそれでは不整合が起きてしまいかねません)
START TRANSACTIONを使用することで、自動コミットが無効になります。そのためCOMMITクエリを実行しなければなりません(手動コミット)。
ちなみに『PostgreSQL』では、どちらも同じです。
「START TRANSACTION」が元からあったもので「BEGIN」がPostgreSQLの拡張コマンドとのことです。
トランザクション終了
トランザクションの終了には、以下のどちらかのクエリを使用します。
- COMMIT
- データが永続化される
- START TRANSACTION
- 変更が取り消される
トランザクションの書き方の例
それでは、実際にトランザクションを書いていきましょう。ここではMySQLでの書き方になります。
# トランザクション開始
START TRANSACTION;
# idが14のユーザを「山田太郎」へ更新
UPDATE user
SET name = "山田太郎"
WHERE id = 14;
# idが15の「田中花子」をデータ登録
INSERT INTO user
VALUES(15, "田中花子");
# トランザクション終了
COMMIT;
ちなみに以下のようにすると、userテーブル全件が「山田太郎」となってしまうため要注意です⚠️
UPDATE user
SET name = "山田太郎";
余談になりますが、UPDATEクエリには必ず「WHERE」句をつけるようにしましょう。
※MySQLには「–safe-updates」オプションがあり、これが有効になっているとWHERE句なしのUPDATE・DELETEが実行できなくすることができます。
トランザクションについては以上になります!
お疲れ様でした!
【おまけ】基本情報技術者試験の問題を見てみよう!
1件のトランザクションについて80万ステップの命令実行を必要とするシステムがある。プロセッサの性能が200MIPSで,プロセッサの使用率が80%のときのトランザクションの処理能力(件/秒)は幾らか。
- ア:20
- イ:200
- ウ:250
- エ:313
正解:イ
一つのトランザクションはトランザクションを開始した後,五つの状態(アクティブ,アボート処理中,アボート済,コミット処理中,コミット済)を取り得るものとする。このとき,取ることのない状態遷移はどれか。
遷移前の状態 | 遷移後の状態 | |
ア | アボート処理中 | アボート済 |
イ | アボート処理中 | コミット処理中 |
ウ | コミット処理中 | アボート処理中 |
エ | コミット処理中 | コミット済 |
正解:イ
参考ページ
今回の記事を書く際に参考にしたページです。
- START TRANSACTIONについて
- BEGINについて
- 各DBMSでのトランザクションの書き方
- START TRANSACTIONの未使用時の部分を参考
- PostgreSQLのBEGINとSTART TRANSACTIONの違いについて
- COMMITについて
- UPDATEクエリにはWHERE句をつけるべきという件について
- 「–safe-updates」オプションについて