ACID特性 by データ指向アプリケーションデザイン

ふわっと理解して忘れてを繰り返しているACID特性について
自分の理解を固めるために『データ指向アプリケーションデザイン』という書籍での説明(7.1節)を参考にまとめた。

tl;dr

  • A: 原子性(atomic)

  • C: 一貫性(consistency)

    • データベースを利用するアプリケーションの特性であり、データベースだけの責務ではない
    • 原子性や分離性によって支えられる
    • データについて常に真でなければならないことが守られていること
      • 例えば、会計システムで貸方と借方が等しくなければならないこと
  • I: 分離性(isolation)

    • 複数のトランザクションにおいて、並行に実行されることによって生じる問題が起きないこと
    • 直列化可能性(Serializability)を分離性とされることもあるが、実際の実装ではそれよりも弱い分離性が使われている。
  • D: 永続性 (durability)

    • コミットが成功したデータは、障害時にも失われないことを示す。

A: 原子性 (atomic)

まず原子性について、マルチスレッドプログラミングでもアトミックな操作というものが出てくるが、それとACID特性の原子性は似て非なるものであると言われている。

例えばマルチスレッドプログラミングにおいては、あるスレッドがアトミックな処理を実行しているというなら、それは他のスレッドからはその処理の半分だけ完了した途中の状態を見る方法が存在しないことを意味します。 (中略) これに対し、ACIDの文脈における原子性は並行性とは関係ありません。これは複数のプロセスが同じデータに同時にアクセスしようとした時に起こることを記述するものではありません。なぜならこれはACIDのIが表す分離性(isolation) が取り上げていることなのです。

とのこと。
それ以上小さな単位に分割できない、という意味では同じだが、
マルチスレッドプログラミング原子性: 他のスレッドから、途中の状態を見れない
ACIDにおける原子性: 1つのトランザクションが実施された場合、途中の状態で終了することがない
という違いがある。

次に、ACIDにおける原子性について以下のように説明されている。

あるクライアントが複数の書き込みを行おうとして、いくつかの書き込みが処理された後に、例えばプロセスのクラッシュやネットワーク接続の途絶、ディスクフル、あるいは何らかの整合性違反といった障害が発生したような場合に起こることです。仮に複数の書き込みがアトミックなトランザクションにグループ化されており、それらを含むトランザクションが障害のために完了(コミット)しなかったら、そのトランザクションは中断され、データベースはそのトランザクション中でその時点までに行われた書き込みは、すべて破棄もしくは取り消ししなければなりません。

つまり、他のトランザクションから途中の状態を見れないことを保証するのではなく、障害が起きて失敗した場合にちゃんと切り戻すことを保証する性質である。

おそらくは中断可能性(abortability)の方が原子性よりも良い言葉だったと思われます

なるほど。

C: 一貫性 (consistency)

一貫性については以下のように説明されている。

ACIDにおける一貫性という概念は、データについて常に真でなければならない何らかの言明(不変性)があるということです。たとえば会計システムの場合、すべてのアカウントでまとめれば常に貸方と借方は等しくならなければなりません。

これはあくまでアプリケーションが担保しなければならないものであり、データベースは原子性や一貫性によってこれを支えるものであると書かれている。

とはいえ、この一貫性の概念はアプリケーション固有の不変性の概念に依存しており、一貫性を保つようにトランザクションを適切に定義することは、アプリケーションの責任になります。これはデータベースが保証できることではありません。

さらには、一貫性はACIDには不要とまで書かれている。

Cは実際にはACIDに属していないのです。

I: 分離性(isolation)

これが有名なトランザクションの分離レベルと関係のある分離性である。

ACIDにおける分離性とは、並行して実行されたトランザクションがお互いから分離されており、お互いのつま先を踏みつけあるようなことがないという意味です。

古典的な教科書では直列化可能性として形式化されているが、実際にはパフォーマンスが悪いので直列化可能な分離性が用いられることはほとんどなく、より弱い分離レベルが使われる。

永続性 (durability)

永続性はわかりやすい。 トランザクションが成功したら、クラッシュしてもデータが守られているという性質。

永続性は、トランザクションのコミットが成功したら、仮にハードウェアの障害やデータベースのクラッシュがあったとしても、そのトランザクションで書き込まれたすべてのデータは失われないことを約束するものです。

感想

ふわっと理解して忘れてを繰り返しているのは、原子性、一貫性、分離性がごっちゃになりやすいからだと思った。 マルチスレッドプログラミングの文脈で、原子性と分離性を混同しやすいし、 一貫性は原子性や分離性によって成り立つものであることも混同の元だった。

この本で原子性はマルチスレッドプログラミングのものとは別物と言い切ってくれたのと、CはACIDではないと言ってくれたおかげで理解が進んだ。