The Scalable Relational Database Server

本ドキュメントでは、データベースの、トランザクションや、アイソレーションレベル、ロック機構の原則、更新可能性について簡単に解説する。これらのコンセプトはすべて、FrontBaseデータベースへのアクセスに関して、同一性を保つために使われる。

同時アクセス(Simultaneous access

データベース・サーバの、もっとも基本的な特徴の1つに、複数のユーザに対し、データを共有しながら並行してアクセスすることを許す、という概念がある。これにより、データベース・サーバは、データベースに対する更新を、順序立てて行う必要がある。そうしなければ、データが腐ったり、なくなってしまうからだ。

トランザクション(Transactions

トランザクションは、データベースへのユーザ・アクセスを制御するために使われる。どのユーザも、トランザクションなしには、データベースへはアクセスできないし、データベースに対する操作はすべて、トランザクションのコンテキストに沿って実行される。あるユーザがデータベースに加えた変更はすべて、トランザクションが実行されたとき、他のユーザに対して見えるようになる。トランザクションは、外からみると、まるで、1つの原子的操作に相当する。

トランザクションの実行に失敗すると、その失敗したトランザクションをコミットできず、(そのトランザクションは、次回には失敗しないという希望がもてるなら)まったく最初からやり直すしかない。データベース・サーバは、原則として、失敗したトランザクションを再実行することができるが、優れたサーバならば、トランザクションの失敗には、それなりの理由があるはずである。それなりの理由とは、デッドロックに他ならない。

トランザクションが生成されたとき、アイソレーション・レベルや、更新可能性、ロック機構原則といったものが割り当てられる。アイソレーション・レベルは、トランザクションを、他のトランザクションに対して、どれくらい孤立させるかという度合いであり、更新可能性は、アクセスを読み取りのみにするか、読み書き両方にするかを指定するものである。ロック機構原則は、データベースアクセス時の同期に使われるロック種類を決定するものである。

更新可能性(Updatability

更新可能性とは、読取専用か、読み書き可能のどちらかである。更新可能性が読み取り専用の場合、トランザクションは、データベースを編集できない。この更新可能性は、きわめて重要である。なぜなら、読み取り専用のトランザクションとは、相容れないからである。

アイソレーション・レベル

SQL92 では、4段階のアイソレーション・レベルを定めている:

READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
さらに、FrontBaseで、もう1段階のアイソレーション・レベルを定義している: VERSIONED
データベース中のデータにユーザがアクセスする場合、以下のような現象を経験するだろう:
読み込み不良(Dirty reads)

1つめのトランザクションが、データベースにデータを書き込み中であり、2番目のトランザクションは、そのデータを読み込んでいるという場合、最初のトランザクションは現在進行中である。2番目のトランザクションは、実際には存在していないデータを読んでいるということになる。

反復読み込み不可(Non-repeatable Read)

トランザクションは、行を読んでいる。2番目のトランザクションは、行の値を更新し、COMMITをしていることになる。最初のトランザクションが、再度行を読もうとしたとき、返される結果が異なるだろう。

見せかけの結果(Phantom)

1つ目のトランザクションが、データベース中のあるデータを選択し、2番目のトランザクションが、1つ目のトランザクションで用いられた述部を満足するような行を更新したり、そのような行を挿入する。2番目のトランザクションは、commitされる。もし、最初のトランザクションで再度選択が行われると、異なる結果が得られる可能性がある。
以下に示すテーブルは、現象ごとに、既存のアイソレーション・レベル許可が設定されているものである:

読み込み不良 反復読み込み不可 見せかけの結果
READ UNCOMMITTED YES YES YES
READ COMMITTED NO YES YES
REPEATABLE READ NO NO YES
SERIALIZABLE NO NO NO
VERSIONED NO NO NO

ロックされたデータ全体は、アイソレーション・レベルを反映している。READ UNCOMMITTEDを使った場合は、まったくロックされない。READ COMMITTEDも、まったくロックされないが、commitされたデータのみを読みとる。REPEATABLE READは、選択された行をロックする。SERIALIZABLEは、テーブル全体をロックする。FrontBaseを用いる場合、READ UNCOMMITTEDは、READ COMMITTEDにアップグレードされる。

VERSIONEDというアイソレーション・レベルは、READ ONLYトランザクションについてのみ有効で、トランザクション中、データベースの現状バージョンを維持する働きを持つ。ほかのトランザクションでは、データベースを変更することがあるかもしれないが、VERSIONEDトランザクションに対しては、加えられた変更を見ることはできない。VERSIONEDトランザクションは、いくつでも同時進行可能で、commitされたデータベース・バージョンを共有している。

ロックの原則(Locking Discipline

更新性とアイソレーション・レベルに加えて、FrontBaseには、ロック原則というコンセプトがある。このロック原則には、以下のような値が設定されている:

  • PESSIMISTIC(悲観的)
  • DEFERRED(猶予中:更新可能と呼ばれることもある)
  • OPTIMISTIC(楽観的)

PESSIMISTICロックとは、既存のオブジェクトが変更された場合、トランザクションはオブジェクトが利用可能になるまで待ち続ける(これでロック解除)と仮定するものである。トランザクションが待機している愛だ、デッドロックする可能性もある。トランザクションの1つがデッドロックを起こすと、デッドロックが検知され、切断される。

OPTIMISTICは、既存のオブジェクトが、他のトランザクションによって変更されることはないと仮定するもので、将来的にどんな面倒がおきようと関係なく、変更を実施するものである。トランザクションがcommitされると、アクセスされたオブジェクトは、トランザクション中は変更されない。もし、変更された場合、commitは失敗する。

DEFERREDは、PESSIMISTICロックのように、オブジェクトは読み取り専用と仮定し、最初に読み取りに対してのみロックをかけ、もしオブジェクトが更新されようとしたとき、書き込みロックにアップグレードするものである。

ロックとEOF

EOFは、OPTIMISTIC ロックで用いられ、フェッチ(取り出し)でトランザクションを開始し、変更が保存されたときにトランザクションを終了する。EOFは、オブジェクトが更新中であるかをチェックするだけのもので、それ全体が正しいか、全オブジェクトが正しくアクセスされるかをチェックするものではない。ユーザは、いくつもの行をロードし、何らかの計算を行い、結果を、1つの行にストアする。計算に用いられた全行が変更されたようなケースでは、結果をチェックすることは不可能なため、結果に間違いが含まれている可能性もある。

FrontaBaseは、OPTIMISTICロックをインプリメントしている。EOFによる問題は、あるユーザーがオブジェクトを選択し、それに加えた変更を保存して、commitしたとき、トランザクションを開始する、という具合に、クライアント側でトランザクションのネストを観とめることで解決可能である。実際のROLLBACKやCOMMITは、ユーザによって利用可能にされるべきである。サーバがロックをインプリメントすると、EOFでのロックは冗長なものとなり、スナップショットなどは、オフにされてしまうだろう。
(c)Copyright 1999-2006 A10 all right reserved.