🦁

ACID特性について

2024/12/07に公開

はじめに

業務でトランザクションを使うことはありますが、ACID特性のAtomicityを意識して使うことが主で、他の性質についてあまり意識することがありませんでした。
今回改めて勉強してみたので備忘録としてまとめてみます。

トランザクションとは

複数のクエリをひとかたまりとして扱うことができる。
トランザクションを使うことでACID特性を担保する事ができる。

ACID特性とは

以下の4つの特性の頭文字を取ったもの。

  • Atomicity
  • Consistency
  • Isolation
  • Durability

Atomicity(原子性)

複数のクエリの実行結果が、「全て成功」もしくは「全て失敗」のどちらかに属さなければ行けないとする性質。
(例: 銀行の送金、宿泊予約など)

Consistency(一貫性)

各種整合性制約(外部キー、ユニーク制約)などによって維持されるレコードの整合性が、データベース操作の前後で維持される性質。

Isolation(分離性)

トランザクションが並行して実行されるときに、それぞれが他のトランザクションに影響されず、あたかも1つずつ順番に(直列に)実行されたように見えることを保証する性質。
この性質はレコードの読み取りに制限をかけることで担保されるため、スループットとトレードオフの関係になる。

トランザクション間の分離性を担保しないことで発生する問題例として以下が挙げられる。

  • Dirty Read
    別トランザクションのコミットされていない変更読み取れてしまい、それに依存したデータ操作を行ってしまう
  • Fuzzy Read
    同じクエリを実行しても、別トランザクションの変更コミット前後で実行結果が変わってしまう
  • Phantom
    別トランザクションでのレコードの挿入・削除により、SELECTで取得できる行数が変化する

分離性のレベルは以下の4つに分けられ、それぞれで読み取りの結果が異なる。

  1. Read Uncommitted
    別トランザクション内のコミットの変更を読み取り可能。
  2. Read Committed
    別トランザクション内のコミットのデータのみ読み取り可能。
    Dirty Readを防ぐ事ができる。
  3. Repeatable Read
    初回クエリの結果で2回目以降のクエリ結果が固定され、他トランザクションの更新の影響を受けない。
    初回クエリ実行時点ですでにコミットされているデータで固定することに注意。
    Fuzzy Readも防ぐことができる。
    MySQLのデフォルトの分離レベル。
  4. Serializable
    他トランザクションによる全ての更新、挿入、削除の影響を受けない。
    Dirty, Fuzzy, Phantom全て防ぐことができる。

トランザクション内で更新前のデータは、ロールバックセグメントという領域にバージョン管理される。
分離レベルごとに参照するバージョンを変えることで読み取り結果を制御している。

Durability(持続性)

コミットが完了すれば、その結果の永続性が保証される性質。
仮にシステム障害が発生しサーバーがダウンしても、事前にトランザクションのログをディスクに残しておくことで再起動時にログを元にトランザクションを復元できる。

参考文献

https://www.shoeisha.co.jp/book/detail/9784798185330

Discussion