📦

トランザクションとは【RDB】

2024/03/24に公開

トランザクションについて改めて勉強したのでまとめまてみました。

トランザクションとは

言葉の意味

そもそもトランザクション(transaction)という言葉には、

  • 取引、商取引
  • 経済活動

などの意味がありますが、RDB の世界では「データベースに対する 1 つ以上の更新をまとめて呼ぶ時の名前」のことをいいます。
ここの「更新」というのは、「複数の SQL 文によるデータベース更新」のことです。
一般的にトランザクションを作ることを「トランザクションを張る」みたいに言ったりします。

そもそもトランザクションは必要?

特定の処理をするにあたって、複数の更新(INSERT / DELETE / UPDATE)を同時にしなければいけない場面は多いです。
それらの更新処理の最中に何かしらの要因で処理が中断されたりすると、データの整合性が取れなくなる可能性あるので、複数の更新処理をまとめてトランザクションにすることで、データの安全性を担保することができます。

トランザクションが使用される例

具体的にトランザクションが使用される例を少し載せてみました。
以下の処理にトランザクションを張らず、途中で中断されるとデータの整合性が取れなくなってしまいます。

① 預金の口座振替

  1. 口座 A から ¥10,000 を引き落とす
  2. 口座 B に ¥10,000 を入金

② オンライン注文

  1. ユーザーが商品 A を 1 つ購入
  2. 商品 A の在庫を 1 つ減らす
  3. 商品 A の売り上げを更新
  4. カートから商品 A を削除

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

トランザクションを張るには、更新する DML 文(INSERT / DELETE / UPDATE)を

  • トランザクション開始文
  • トランザクション終了文

で囲ってあげる必要があります。

トランザクション開始文;

-- DML①;
-- DML②;
-- ...

トランザクション終了文;

トランザクション開始文

MySQL のトランザクション開始文はSTART TRANSACTION;を使用します。

START TRANSACTION;

-- DML①;
-- DML②;
-- ...

トランザクション終了文;

トランザクション終了文

トランザクション終了文はCOMMIT;またはROLLBACK;を使用します。

  • COMMIT;:更新を確定して DB に反映をする
  • ROLLBACK;:更新を全て破棄し、トランザクション前の状態に戻す
START TRANSACTION;

-- DML①;
-- DML②;
-- ...

COMMIT;
または
ROLLBACK;

実際にトランザクションを使ってみる【MySQL】

実際に MySQL でトランザクションを貼ってみます。
※先ほどの例を使用

① 預金の口座振替

  1. 口座 A から ¥10,000 を引き落とす
  2. 口座 B に ¥10,000 を入金
START TRANSACTION;

-- 口座 A から ¥10,000 を引き落とす
UPDATE account SET balance = balance - 10000 WHERE account_id = 'A';

-- 口座 B に ¥10,000 を入金
UPDATE account SET balance = balance + 10000 WHERE account_id = 'B';

COMMIT;

今回はCOMMITで確定をしていますが、破棄したい場合はROLLBACKにすれば問題ないです。

備考

ACID 特性

トランザクション自体には守るべき約束事の「ACID 特性」というものが標準規格によって決まっており、ACID 特性を満たすように RDBMS のトランザクション は設計されています。
※それぞれの約束事の頭文字をとって「ACID(アシッド)」となっています。

Atomicity(原子性)

トランザクションが終わったとき、そこに含まれていた更新処理は全て実行されるか、実行されないことを保証する性質。
全て実行される(COMMIT) or 全て実行されない(ROLLBACK

Consistency(一貫性/整合性)

トランザクション内の処理はあらかじめデータベースに設定された制約を満たし、データに一貫性を持たせる性質。
ex)主キー制約や NOT NULL 制約に違反した場合はその更新のみ処理が実行されない

Isolation(独立性/分離性)

トランザクション同士がお互いに干渉を受けないことを保証する性質。
更新途中のトランザクション同士が干渉すると、データに不整合が起きる可能性があるので、トランザクション実行中は他のトランザクションから隠蔽されます。

Durability(永続性)

トランザクションが終了した時点で結果が記録されることを保存する性質。
トランザクション内で行った更新処理は永続的に残り、結果は失われない

トランザクション分離レベル

どこまでトランザクション同士を分離させ、隠蔽するのかをレベルとして表したものです。
※ACID 特性の中の「Isolation(分離性)」に当てはまります。

トランザクションを隠蔽しないと他のトランザクションから読み取ることができるので整合性が保てなくなったり、隠蔽しすぎると並列でトランザクションを処理できなくなるのでパフォーマンスに影響が出たりします。
いい塩梅のレベルを設定していいパフォーマンスを出しながら安全にトランザクションしようね、という感じです。

トランザクション分離レベルは奥が深いのでまだまだ勉強不足ですが、参考になりそうな記事がありましたので載せておきます ↓

参考

Discussion