1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ACID特性とトランザクション分離レベルについて

Last updated at Posted at 2025-01-21

ACID特性

ACIDとは?

  1. A (Atomicity:原子性)
    • トランザクション内の処理はすべて完了するか、まったく行われない(All or Nothing)。
  2. C (Consistency:一貫性)
    • トランザクション前後でデータの一貫性を保つ。
  3. I (Isolation:分離性)
    • 複数トランザクションを同時実行しても、相互に影響を受けないようにする。
  4. D (Durability:永続性)
    • コミットされた変更は障害が起きても失われない。

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

Isolation(分離性) を調整するための仕組みです。
下に行くほど分離レベルが高く、整合性が強化されます。

分離レベル 特徴 発生しうる問題 デメリット
Read Uncommitted 未コミットのデータを読む可能性がある ダーティリード、ノンリピータブルリード、ファジーリード、ファントムリード 整合性がほぼ保証されない
Read Committed コミット済みデータのみを読み取るため、ダーティリードを防ぐ ノンリピータブルリード、ファジーリード、ファントムリード パフォーマンスと整合性のバランスが必要
Repeatable Read 同じトランザクション内で同じ行を読むと、同じ値が返る
ノンリピータブルリードを防ぐ
ファントムリード ロック範囲が広がり、パフォーマンス低下
Serializable 強制的にトランザクションを直列実行したかのように扱う 問題なし(すべて防ぐ) 大量のロックによりスループットが低下

不整合の例

1. ダーティリード(Dirty Read)

  • 概要: 他のトランザクションが未コミットのデータを読み取ってしまう。
  • :
    1. トランザクションA: 顧客の残高を「5000」→「4000」に変更(未コミット)。
    2. トランザクションB: 未コミットの「4000」を読み取る。
    3. トランザクションA: ロールバックして残高が「5000」に戻る。
    • 結果: トランザクションBは誤った値「4000」を使用してしまう。
  • 回避: Read Committed以上を使用。

2. ノンリピータブルリード(Non-Repeatable Read)

  • 概要: 同一トランザクション内で同じ行を再度読み取ったときに、他トランザクションの更新によって値が変わる。
  • :
    1. トランザクションA: 「顧客ID=1」の残高を読み取る(最初は5000)。
    2. トランザクションB: 「顧客ID=1」の残高を「6000」に更新しコミット。
    3. トランザクションA: 再度「顧客ID=1」の残高を読み取る → 今度は「6000」。
    • 結果: 1回目2回目で値が異なる。
  • 回避: Repeatable Read以上を使用。

3. ファジーリード(Fuzzy Read)

  • 概要: 同じ条件のクエリを複数回実行した際、読み込む行の一部または値が他のトランザクションで更新され、データセット全体が不一致となる。
  • :
    1. トランザクションA: WHERE balance >= 4000 で顧客リストを取得。
    2. トランザクションB: 既存顧客の残高を変更(例: 5000→3000)してコミット。
    3. トランザクションA: 再度同じ条件(WHERE balance >= 4000)で取得 → 前回とは異なる行が返る可能性。
    • 結果: 同じ条件のクエリでも行数や内容が前回とは異なる状態になる。
  • 回避: Repeatable Read以上を使用(ただし、ファントムリードほど厳重な対策ではない)。

4. ファントムリード(Phantom Read)

  • 概要: 同じ検索条件で再度クエリを実行した際、他のトランザクションによる行の追加・削除で結果行数や集計値が変化する。
  • :
    1. トランザクションA: SELECT SUM(balance)1,000,000円
    2. トランザクションB: 新規口座を追加(100,000円)してコミット。
    3. トランザクションA: 再度同じクエリ → 今度は 1,100,000円
    • 結果: 前回の検索結果とは行数が異なり、「幻の行(Phantom)」が紛れ込む形となる。
  • 回避: Serializableを使用。

運用上の注意

  • 性能: 分離レベルが高いほどロック競合が増え、スループットが低下する。
    • ロック競合: 複数トランザクションが同じデータを同時アクセスする際、整合性を保つために発生する待機やブロック。
    • スループット: データベースの処理能力。
  • 整合性: 分離レベルが低いほど不正確なデータを読み込むリスクがある。
  • 選択基準: 必要なデータ整合性とパフォーマンス要件のバランスを考慮する。
  • 通例的なデフォルト: ダティーリードを回避する ReadCommited が使われがち。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?