まえがき
今までシリアライザブルなトランザクションをサポートするための仕組みについて説明・実装してきました。果たして、これでACID特性がどのように実装されたのかについて振り返ってみましょう。
Atomicity(原子性)→△
原子性が守られているか検証してみる。トランザクションは高々一つしか実行できないので、各トランザクションの中で、原子性が守られれば良いということになる。
コミットしない場合(トランザクションのキャンセル・アボート)
gitと同じように、トランザクション内での変更は各ローカル環境のみに閉じ込めておく実装にしたため、COMMIT以前にトランザクションがキャンセル、もしくはアボートされた場合はローカル環境を潰すだけでトランザクションがなかったことにできる。
コミットした場合
トランザクションをCOMMITした場合はローカル環境の変更を共有データ領域に書き込むことになるが、もし共有データ領域の書き込み途中でプロセスが死んだりすると残念ながらデータベースは不整合な状態になる。
したがって、原子性を担保するためには、コミット途中でプロセスが死んだりエラーが発生した場合の処理について別途実装が必要である。
Consistency(一貫性)→✕
RDBにおける一貫性の定義はいくつかあると思うが、「トランザクションが実行されたとき、データベースが次の状態に遷移し、それが想定通りでないことはない。」とするならば、原子性が満たされていない状態なので、一貫性も満たさない。
データベースは各トランザクションの実行ごとに次の状態へと遷移していく。◯から◯へと。この◯から外れた状態に落ちることはあってはならないべき。しかし、トランザクションのコミット途中にプロセスが落ちれば、DBは中途半端な状態へと落ちてしまう。当然その後に続くトランザクションの処理も想定していない状態へと影響を与えてしまう。
一貫性を担保するには、マリオカートで道を外れたときに救い上げてくれる「じゅげむ」のような存在が必要ということである。
Isolation(独立性)→◯
今のところトランザクションは複数同時に実行できない前提であるため、トランザクションの分離レベルでいうSerializableが実装できた。
Durability(永続性)→✕
共有データ領域を保持しているプロセスが死ぬと、メモリ上のデータが吹き飛ぶため永続性は明らかに担保されていない。もし、すべてのデータをファイルに書き込むことにした場合は、永続性がある程度担保される。なぜなら、プロセスが死んだとしても、プロセスを再起動し、ファイルを読み込むことでデータを復旧できるからである。プロセス再起動→データリカバリの手続きも実装しなければいけない。エラーリカバリについては、様々なケースが考えられるのでまとめて設計・実装する。
まとめ
Atomicity | △ |
Consistency | ✕ |
Isolation | ◯ |
Durability | ✕ |
トランザクションを高々一本しか実行できないように制限すると、ローカル/共有のデータ空間を分けることによって、ACID特性の一部分が実装できた。これからはエラーリカバリの挙動について、設計・実装していきAtomicity、Consistency、Durabilityを実装していく。
複数トランザクションをスケジューリングして、実行していく部分はさらにその後に。