🦁
ACID特性について
はじめに
業務でトランザクションを使うことはありますが、ACID特性のAtomicityを意識して使うことが主で、他の性質についてあまり意識することがありませんでした。
今回改めて勉強してみたので備忘録としてまとめてみます。
トランザクションとは
複数のクエリをひとかたまりとして扱うことができる。
トランザクションを使うことでACID特性を担保する事ができる。
ACID特性とは
以下の4つの特性の頭文字を取ったもの。
- Atomicity
- Consistency
- Isolation
- Durability
Atomicity(原子性)
複数のクエリの実行結果が、「全て成功」もしくは「全て失敗」のどちらかに属さなければ行けないとする性質。
(例: 銀行の送金、宿泊予約など)
Consistency(一貫性)
各種整合性制約(外部キー、ユニーク制約)などによって維持されるレコードの整合性が、データベース操作の前後で維持される性質。
Isolation(分離性)
トランザクションが並行して実行されるときに、それぞれが他のトランザクションに影響されず、あたかも1つずつ順番に(直列に)実行されたように見えることを保証する性質。
この性質はレコードの読み取りに制限をかけることで担保されるため、スループットとトレードオフの関係になる。
トランザクション間の分離性を担保しないことで発生する問題例として以下が挙げられる。
-
Dirty Read
別トランザクションのコミットされていない変更読み取れてしまい、それに依存したデータ操作を行ってしまう -
Fuzzy Read
同じクエリを実行しても、別トランザクションの変更コミット前後で実行結果が変わってしまう -
Phantom
別トランザクションでのレコードの挿入・削除により、SELECTで取得できる行数が変化する
分離性のレベルは以下の4つに分けられ、それぞれで読み取りの結果が異なる。
-
Read Uncommitted
別トランザクション内のコミット前の変更を読み取り可能。 -
Read Committed
別トランザクション内のコミット後のデータのみ読み取り可能。
Dirty Readを防ぐ事ができる。 -
Repeatable Read
初回クエリの結果で2回目以降のクエリ結果が固定され、他トランザクションの更新の影響を受けない。
初回クエリ実行時点ですでにコミットされているデータで固定することに注意。
Fuzzy Readも防ぐことができる。
MySQLのデフォルトの分離レベル。 -
Serializable
他トランザクションによる全ての更新、挿入、削除の影響を受けない。
Dirty, Fuzzy, Phantom全て防ぐことができる。
トランザクション内で更新前のデータは、ロールバックセグメントという領域にバージョン管理される。
分離レベルごとに参照するバージョンを変えることで読み取り結果を制御している。
Durability(持続性)
コミットが完了すれば、その結果の永続性が保証される性質。
仮にシステム障害が発生しサーバーがダウンしても、事前にトランザクションのログをディスクに残しておくことで再起動時にログを元にトランザクションを復元できる。
参考文献
Discussion