ACID (コンピュータ科学)
ACIDとは、信頼性のあるトランザクションシステムの持つべき性質として1970年代後半にジム・グレイが定義した概念で、これ以上分解してはならないという意味の不可分性(英: atomicity)、一貫性(英: consistency)、独立性(英: isolation)、および永続性(英: durability)は、トランザクション処理の信頼性を保証するために求められる性質であるとする考え方である[1]。
この語はその4つの性質を表す英語の単語の頭文字をとって作られた頭字語であり、1983年にアンドレアス・ロイター[2]とテオ・ヘルダー[3]によって提唱された。
概要
編集データベースにおいては、データに対する一つの論理的操作の事をトランザクションと呼ぶ。ACIDの各性質を銀行での口座間送金を例にして示す。
不可分性(Atomicity)
編集トランザクションに含まれるタスクが全て実行されるか、あるいは全く実行されないことを保証する性質をいう。アトミック性、原子性とも呼ばれる。 口座Aから口座Bに対し1万円送金する場合を考えたとき、送金操作は次の2操作によって行われる。
- 口座Aの残高から1万円を引く
- 口座Bの残高に1万円を加える
不可分性が保証されるとは、上の操作1、2が全て行われるか、あるいは全く行われないことを指す。どちらか片方だけが実行された場合、銀行全体の預金残高に矛盾が発生してしまう。
一貫性(Consistency)
編集日本語では一貫性あるいは整合性とも呼ばれる。トランザクション開始と終了時にあらかじめ与えられた整合性を満たすことを保証する性質を指す。すなわち、データベースのルール、つまり整合性条件を満たさない状態を起こすようなトランザクションは実行が中断される。
預金残高を例にすると、その値は一般的に0あるいは正の値を取る条件を満たす必要がある。よって、口座Aから送金を行うとき、その前後でAの口座残高が負になるような額は送金できないようにする。このようなルールを保証するのが一貫性の役割である。
独立性(Isolation)
編集トランザクション中に行われる操作の過程が他の操作から隠蔽されることを指し、日本語では分離性、独立性または隔離性ともいう。より形式的には、独立性とはトランザクション履歴が直列化されていることと言える。この性質と性能はトレードオフの関係にあるため、一般的にはこの性質の一部を緩和して実装される場合が多い。
預金残高の例では、残高100万円の口座Aから残高200万円の口座Bに1万円送金する場合の操作が
- 口座Aの残高から1万円を引く
- 口座Bの残高に1万円を加える
の順序で行われたとする。取りうる内部状態は、
時点 | 口座A | 口座B |
---|---|---|
送金前 | 100万円 | 200万円 |
実行中 | 99万円 | 200万円 |
送金後 | 99万円 | 201万円 |
の3つになるが、外部からは送金前と送金後のいずれかの状態しか観測できない。
永続性(Durability)
編集永続性あるいは持続性と呼ばれる。トランザクション操作の完了通知をユーザが受けた時点で、その操作は永続的となり、結果が失われないことを指す。これはシステム障害に耐えるということであり、DBMSは整合性制約をチェック済みでありトランザクションを中止してはいけないということである。多くのデータベース実装では、トランザクション操作を永続性記憶装置上にログとして記録し、システムに異常が発生したらそのログを用いて異常発生前の状態まで復旧することで永続性を実現している。
実装
編集トランザクションによる状態の変更は、例えばデータ自体に加えそれに付随するインデックスの更新のように、複数の変更によって構成される場合が多く複雑である。また、厳密にACIDを実装しようとすると、広範囲なロックを取得したり、多くのデータを複製するなどといった、性能面での劣化が大きくなりすぎることがある。ACIDを厳密に実装することは難しい。
また、ACIDを実現する手続き自体がシステム要因にて失敗してしまう場合もあり、その失敗要因を回避した後に復旧できるような対処を取る必要がある。例えば、UNIXのファイル実装に関して、ジャーナルファイルシステムによるファイルの一貫性の保護や、データのフルバックアップなどの対処など、多くの改善と処理の工夫が取り入れられている。
ACIDはデータベースが全ての処理を一度に処理できることを要求している。実際にはこの処理の手筈を整えるのは難しい。しかし、これを行うのにログ先行書き込み(英: write ahead logging)とシャドウページングという2つの一般的なテクニックが存在する。どちらの場合でも、読み書きする情報全てに対してロックを取得しておかなくてはならない。ログ先行書き込みの場合、データベースへの実際の書き込みが行われる前にすべてのredo リドゥと
複数のトランザクションを並行実行するときは、独立性の実現に注意するべきである。実際には、完全な独立性の実現はコストが高いため、実現するトランザクション分離レベルを設定し、実装することとなる。また、分離レベルの実装はデッドロックやライブロック等に注意して行うべきである。例えばツーフェーズロッキング等が一般的に利用される。
トランザクションに関わる参加者が複数の場合、例えばツーフェーズコミット(2PC)が一般的に利用される。ツーフェーズコミットでは各参加者がトランザクションのコミットに同意するか否かについて一致することを保証する。