Microservice and Transaction Management2  トランザクションの原則：ACID特性とCommitment Ordering1

# はじめに

日立製作所 クラウドビジネス推進センタの西谷です。

[前回](https://qiita.com/j-nishitani/items/7a6582b4d9cecdb12801)は、マイクロサービスのトランザクション管理に関する動向と、現在提唱されているSagaパターンについて軽く触れましたが、その目的となる矛盾を防止する能力＝整合性を理解するためには、分散トランザクションのACID特性を考えるのがよいと思います。この特性は、「厳密にACIDを実現するのは困難」とか「クラウドではBASEが基本」といった風潮によって、昨今触れられることが少なくなったように思いますが、実はこの整合性の議論において重要な理論の入り口となる特性となります。

そのため、今回は分散トランザクションのACID特性の主に「A」「C」「I」の関係を説明し、次回はACID特性の前提となる理論、[Commitment Ordering](https://en.wikipedia.org/wiki/Commitment_ordering)を扱おうと思います。


[Commitment Ordering](https://en.wikipedia.org/wiki/Commitment_ordering) まで見ていくと整合性を実現するために必要な機能が見えてきます。

## 本シリーズの予定

1. [マイクロサービストランザクションの動向(前回)](https://qiita.com/j-nishitani/items/7a6582b4d9cecdb12801)
2. __トランザクションの原則：ACID特性とCommitment Ordering前編(今回)__
3. [トランザクションの原則：ACID特性とCommitment Ordering後編](https://qiita.com/j-nishitani/items/5f7a9afe3130a11acd9a)
4. [合意理論からみる2Phase CommitとMicroserviceマイクロサービス](https://qiita.com/j-nishitani/items/c8deefd151de0f4e49b0)
4. 結果整合性は本当に整合するのか

# ゴール

- ACIDのそれぞれの特性の関係を理解する

# ACID特性の前提：データの状態遷移
まず、ACID特性に触れる前に、データベースの基本に立ち返ってみようと思います。
データベースの主な目的は、「特定のデータを蓄えておく」ことにありますが、継続的に稼働するような類のデータベースであれば、外部からのトリガーによってデータの内容が継続的に更新されていくことになります。


前回の例でいえば、「500円を振り込む」というデータベース外からの更新要求のようなトリガーをきっかけとして、二つのデータベースが新しい状態に遷移します。ここで遷移前を「現状態」とし、遷移後を「新状態」とでもしておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/69e9fdae-b494-c829-5d61-f0fde1cd5967.png)
「新状態」として状態が確定した後は、それがデータベースの「現状態」となり、また外部からのトリガーにしたがって「新状態」に移行する。このようにして、システムが稼働し続けている間、永遠にこの状態遷移を繰り返していくというわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/adebc484-bb71-5273-5cf8-42a8c4a91fc0.png)


# 状態・状態遷移とACID特性の関係
さて、データを扱うシステムで分散トランザクションを搭載する目的は、(何度もいいますが)「データベース間で発生する可能性がある矛盾を防ぐ」ことにあると言いましたが、この「矛盾」を先述のデータの状態遷移の中で定義するとしたら __「システムに、"新状態に移行したデータ"と"新状態に移行していないデータ"が混ざること」__ と言えると思います。

銀行間取引で、口座Aからは引き出したのに口座Bに振り込まれていない、という失敗を例に考えてみると、引き出しの成功した口座Aの残高が「新状態に移行したデータ」であり、振込に失敗した口座Bの残高が「新状態に移行していないデータ」ということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/76883f9b-95d3-b5c5-f10a-38a155211a6e.png)


このように考えると、矛盾を防ぐにはどうすればよいかは結構単純です。すなわち、データベースの状態遷移で以下を達成すればよいわけです。

1. __関連する全てのデータを新状態に移行させる。__
2. __一部のデータが新状態に移行できないのであれば、関連するすべてのデータを新状態に移行させない。すべてを現状態のまま保持しておく。__

なお、これをトランザクションシステムで備えなければならない性質のひとつ、__Atomicity(原子性)__ と呼びます。ACID特性の頭文字のAであり、別の見方をすると、Atomicityはシステムの中で、 __データの状態遷移を行う仕掛け__ に搭載しなければならない特性と見ることができます。


ただし、状態遷移の最中は個別のデータベースがそれぞれのデータ領域を更新しますが、更新のタイミングはまちまちです。このため、この状態遷移の最中はどうしても現状態と新状態が混ざった、矛盾がある段階が発生してしまい、避けることができません。この遷移中の状態を、別のシステムが参照すると矛盾した状態を参照することになります。この矛盾した情報が伝播すると、最悪の場合、システムのデータを破壊してしまう可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/fec49015-a2ed-fcc2-fae5-6255736d02cf.png)

このため、__遷移中の状態は見えない__ ようにしなければなりません。別の言い方をすると状態遷移中の状態は"隔離"し、参照不可にする。というわけでIsolation (隔離)も状態遷移の特性として必要になるということになります。(もっと詳細を言うと、Isolationは性能とのトレードオフがありますので、段階があるのですが、ここでは説明を割愛)


この原子性と隔離を満たした状態遷移を完了させると、その結果、データベースの状態は矛盾がない状態になる。「矛盾がない」ということは「整合している」ということですから、これがConsistencyという性質ということになるわけです。

まとめると、ACID特性はAtomicity,Consistency,Isolation,Durability の頭文字を取っているためその関係性は対等のように見えてしまってますが、 __状態の整合性(Consistency)を維持するために原子性(Atomicity)と隔離性(Isolation)を備えた状態遷移を行う必要がある__ 、という、目的と手段の関係になっているというのが実態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/0a90ff61-6ff0-8430-8883-6674cdd90ac6.png)


なお、Durabilityとはシステム障害に耐えるために、データベース等の状態を永続化する特性になりますが、ここでは説明を割愛。

ここまで見てもらうと、ACID特性とは、純粋にデータベースの状態・状態遷移に対して意味付けされた特性であることがわかると思います。だとすると、マイクロサービスのようなアプリケーションのアーキテクチャの形態や、クラウド・オンプレミスのようなインフラストラクチャの形態に関わらず、データベースで整合性を扱う限り、この特性の達成は検討すべき項目ではないでしょうか。

# まとめ

今回は、オンラインで分散トランザクションを実現するために必要な特性であるACID特性についてまとめました。

重要なポイントは以下のとおりです。
- ACIDのそれぞれの特性は、実はデータベースの状態と状態遷移に対応している
- ACID特性の特に「A」「C」「I」は、状態の整合性(Consistency)を維持するために原子性(Atomicity)と隔離性(Isolation)を備えた状態遷移を行う必要があるという、目的と手段の関係になっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065206/0c4f0a14-a8ac-cdcd-8193-dbb6363bc28b.png)

ただ、ここまで理解しても、これら特性の達成のために必要な機能は具体的には見えてきません。というわけで、次回はACID特性の背後にある理論である、[Atomic Commitment](https://en.wikipedia.org/wiki/Atomic_commit)と[Commitment Ordering](https://en.wikipedia.org/wiki/Commitment_ordering)を扱い、特にAtomicity、Isolationを達成するための機能まで踏み込んでみたいと思います。