Database Transaction (トランザクション)

Database Transaction(トランザクション)とは

  • データベースの状態を変化させるために実行する論理的な作業単位である。
  • データベースのデータを操作する作業単位(Unit of work)である。
  • トランザクションでは複数の演算が実行されることがある。
  • トランザクションは、実行中に 1 つでも作業が失敗するとすべてロールバックされ、すべて成功すると commit を実行する。

Transaction ACID とは

  • 原子性(Atomicity)
    • 1 つのトランザクションの作業が、その一部だけ実行されたり中断されたりしないことを保証することをいう。
  • 一貫性(Consistency)
    • トランザクションの作業が正常に完了しても、作業前と同じ有効な状態を維持することをいう。
  • 分離性(Isolation)
    • Transaction 作業が実行されているとき、他の作業が割り込めないように保証することをいう。
  • 永続性(Durability)
    • 正常に実行されたトランザクションについては、永続的(Persistent)に反映されなければならないことをいう。

Transaction を使用する際の注意点

  • トランザクションの範囲は最小化する。
    • トランザクションの範囲を最小化することが重要である。
    • データベースのコネクション数は限定的であるため、コネクションを保持する時間を最小化する必要がある。
    • そうしないと、他のサービスがそのコネクションを使用するために待機しなければならない状況が発生する。

Transaction isolation level の種類と特徴

  • READ UNCOMMITTED
    • SELECT クエリ実行時に、他のトランザクションで COMMIT されていないデータを読み取ることができる。
    • COMMIT されていないデータを読む現象を Dirty read という。
    • INSERT だけが行われ、ROLLBACK される可能性のある、つまり COMMIT されていないデータを読むことができるため注意が必要である。
  • READ COMMITTED
    • Read Committed は、COMMIT が完了したデータだけが SELECT 時に見えるレベルを保証するものであり、多くの DBMS では Read Committed がデフォルトに設定される。
    • Read Committed では、Read Uncommitted で発生する Dirty read が発生しないことを保証する。
    • トランザクションで COMMIT を実行していなくても、DB にはすでに値が反映されている状態であり、COMMIT 前のデータを保証するには、COMMIT されていないクエリを復旧する過程が必要になる。つまり、この時点では Consistent Read を実行する必要があることを意味する。
    • Read Committed の問題は、1 つのトランザクション内で SELECT を実行するたびにデータが同一であることを保証しない点である。その理由は、他のトランザクションで該当データが COMMIT された場合、COMMIT されたデータを返すのが Read Committed の特徴だからである。
    • このような理由から、Read Committed は Non-repeatable Read とも呼ばれる。
  • REPEATABLE READ
    • Read Committed とは異なり、Repeatable Read は 1 つのトランザクション内で繰り返し SELECT を実行しても、読み取る値が変わらないことを保証する。
    • Repeatable Read トランザクションは、最初に SELECT を実行した時刻を記録し、その後はすべての SELECT でその時点を基準に Consistent Read を実行する。
    • したがって、トランザクション中に他のトランザクションが COMMIT されても、新しく COMMIT されたデータは見えない。
    • その理由は、最初の SELECT 時に生成された SNAPSHOT を読むためである。
  • SERIALIZABLE
    • Serializable は、すべての作業を 1 つのトランザクションで処理するのと同じ、最も高い分離レベルを提供する。
    • Read Committed、Repeatable Read の 2 つに共通する問題は、Phantom Read が発生する点である。
      • Phantom Read とは
        • 1 つのトランザクションで UPDATE 命令が失われたり上書きされたりする、つまり UPDATE 後に COMMIT して再度照会したとき、予想とは異なる値が見えたりデータが失われたりした場合を Phantom Read という。
    • それとは異なり、SERIALIZABLE では SELECT クエリがすべて SELECT … FOR SHARE に自動で変更され、Repeatable Read では防げないいくつかの状況を防止できる。

Commit と Rollback

  • Commit
    • 1 つのトランザクションが終わったとき、完了したことをトランザクション管理者に知らせる。
  • Rollback
    • 1 つのトランザクション処理が異常終了して DB の一貫性を崩したとき、すべての演算を取り消すことをいう。