大規模データベースシステムは、何百万人ものユーザーがアクセスできる何百万もの記録を収納する可能性がある。潜在的に、記録に対する何万件ものデータアクセスが毎秒発生する可能性がある。データベースシステムは、多数のプロセッサ上で実行するプロセスによってアクセスされるデータ記憶デバイスを内含することができる。記憶デバイス及びプロセッサは、ネットワークを介して接続されたさまざまな場所に分散されていてよい。例えば大型小売りビジネスは、その顧客の氏名及び住所を維持する第1の記憶デバイス、在庫リストを維持する第2の記憶デバイス及びその顧客の購買履歴を維持する第3の記憶デバイスを有することが可能である。第1の記憶デバイスはボストンに、第2の記憶デバイスはロサンゼルスにそして第3の記憶デバイスはシカゴに置かれている。各記憶デバイスは、広域ネットワーク(WAN)によってその他と接続されているそれぞれ異なる1台のプロセッサによって管理される。1人の顧客 リーサ(Lisa)が、例えば小売りビジネスによって操作される呼出し処理センター内の1人の社員を通してコーヒーテーブルを発注した場合、その社員は、WANを介して、そのコーヒーテーブルがロサンゼルスの記憶デバイスから入手可能であるか否かをチェックしなくてはならない。この社員は、出荷のための リーサの住所を検索し彼女の購買履歴を更新するためその他の場所にある記憶デバイスにアクセスする必要があるかもしれない。同時に、もう1人の顧客 ロビン(Robyn)が、呼出し処理センター内でもう1人の社員を通して同じコーヒーテーブルを注文する可能性がある。両方の社員共、同じ記憶デバイスから読取り、そのコーヒーテーブルについての同じ在庫記録を更新しようとすることになる。
上述の例では、3つの異なる記憶デバイスは、通常独立した形でアクセスされうる異なるタイプのデータ記録を収納している。上述の例におけるように、多数のプロセッサを使用すると、データアクセスが独立しており、各アクセスが異なるプロセッサ上で並行して実行できるかぎりにおいて、スループット及びロードバランシングに関するデータベースシステムの性能を改善させることが可能である。
分散データベースシステムは、多数のプロセスによってアクセス可能であることから、プロセスが適切に調和されない場合、矛盾が発生する可能性がある。矛盾の例としては、2つのプロセスが2つの異なる値で同時に同じ記録を更新しようとしている(コーヒーテーブルの例のように);1つのプロセスがもう1つのプロセスにより削除されている記録を読みとろうとしている;及び1つのプロセスがもう1つのプロセスによって更新されつつある関連記録にリンクする記録を更新しようとしている、といったものがある。矛盾が発生した場合、同じ又は関連データ記録にアクセスするプロセスの動作は予測不可能な形でインターリーブし、従ってオペレーションの結果は不正なものとなり、データベースシステムのデータの一貫性を破壊する可能性がある。
矛盾を解決するための1つのアプローチでは、プロセスが、1つのデータピース内のデータ入力にアクセスしているときそのデータピース(例えば変数、顧客記録又は、部門データベース)をロックし、プロセスがアクセスを終了した時点でロックを解除するセマフォが使用される。その他のプロセスは全て、いずれかのプロセスが現在それを使用しているか否かを見るためデータピースにアクセスする前にこのセマフォをチェックしなければならない。このアプローチは、ロックできるデータピースの細分性が小さい場合何百万ものデータピースについての何百万ものロックを必要とする可能性があり、そうでなければ、例えば部門データベース全体をロックすることで同じ部門データベース内に偶然記憶されることになった共通の要素をもたないデータセットにアクセスするジョブの効率の良い並行実行が妨げられることから、データベースの細分性が大きい場合には数多くのアクセスをブロックする可能性がある。
矛盾に加えて、大規模なデータベースシステムは同様に不充分なデータアクセスにも苦しめられる可能性がある。記憶デバイス内の1つのデータ記録の位置を特定するためだけにデータベースシステム全体を探索することを避けるため、データ記録の要約情報(例えば目次、インデックス又はクロスリファレンス)が通常、容易に探索できる書式で提供される。ただし、要約情報では、データ記録との一貫性がつねに強化されていないかぎり破損する可能性がある。その上、要約情報を更新するタスクも同様に矛盾を作り出す可能性があり、従って効果的にスケジュールされなければならない。
図1を参照すると、データ処理センタ191は、トランザクションシステム192、ビジネスデータユニット(BDU)22及び更新ストリームプロセッサ(USP)23を内含している。トランザクションシステム192は、(インターネットのような)公衆網195及びローカルエリアネットワーク(LAN)181を含むネットワークを介して、例えばコンピュータをもつ顧客189又はデータ処理センタ191を操作する大規模小売りビジネスのコールセンターオペレータ199であり得る潜在的に何百万人ものユーザーによってアクセス可能なものである。ユーザーは例えばそのそれぞれのワークステーションを通して、商品注文又は住所更新であり得る要求を提出する。
トランザクンョンシステム192には、ワークステーションと通信し、ユーザーから要求を受理し、その要求を自動的にタスク又はジョブ命令198ヘと翻訳するアプリケーションプログラム(図示せず)を実行する1つ以上のサーバー196が内含されている。例えば要求というのは、ビル(Bill)という名の人物のための青のセーターの購買注文であるかもしれない。要求は予め定義された電子書式であり、ジョブ命令198は、ジョブを新規作成するUSP23内のプロセスにとって認識可能な形をしたものである。USP23のためのジョブを新規作成するプロセスはジョブ新規作成プロセス(JCP)350又はプロジューサと呼ばれる。
JCP350によって新規作成されたジョブは、ジョブオブジェクトの形をしている。1つのジョブオブジェクトは、BDU22内に記憶された1つ以上のオブジェクトを指すデータ構造を内含する。ジョブオブジェクトは、BDUオブジェクトに作用するジョブ実行プロセス(JEP)によって実行される命令をも包含している。ジョブとジョブオブジェクトの間には1対1の関係が存在することから、以下ではジョブオブジェクトをジョブと呼ぶことにする。
タスクというのは、それがJEPにより実行されるべき命令を包含するオブジェクトであるという点でジョブと同じであるが、それは必ずしもBDU内に記憶されたオブジェクトを指すわけではない。タスクは必要とあらばジョブを産生することができ、また、タスク及び全ての産生されたジョブが完全であるときアプリケーションプログラムに査定応答を送り戻すことができる。タスクが肯定応答を提供するものである場合には、その肯定応答を伝送するための必要なパラメータ及びメカニズムはタスクオブジェクト内に記録される。タスクは、それが受信されたこと及び実行が保証されていることの肯定応答を提供することもできる。
1つのジョブの実行がもう1つのジョブの実行と矛盾しないことを確認する上で重要な1つのステップとして、トランザクションシステム192のアプリケーションプログラムは、ジョブに対して、ジョブ命令198内に含まれたコンテンションインデックスとよばれる整数を割当てる。各々のコンテンションインデックスは、例えばデータセット180といった共通要素のない予備区画化されたBDU22のデータセットを表わしている。予備区画化には、いかなるオブジェクトもBDU22に付加されないうちに定義されるアルゴリズムが使用される。アルゴリズムはBDUオブジェクト上でのジョブ実行のために最適なロードバランシングを達成するように設計されている。タスクは、直接BDUオブジェクトをアクセスしないことから、任意のコンテンションスペースに割当てされ得る。
各々のデータセット180内では、JEP300がデータセット内の1つのオブジェクトにアクセスしたときもう1つのプロセスがそのデータセット内のもう1つのオブジェクトにアクセスした場合に矛盾が発生し得るという意味でBDUオブジェクトは互いに関係している。同じコンテンションインデックスのジョブが、同じデータセット180内の関連オブジェクトへのアクセスを要求する可能性があり、従ってこれらのジョブではシリアルで実行されなくてはならない;異なるコンテンションインデックスのジョブは、スループットを増大させるべく並行して(同時に)実行することができる。
大型ジョブは、1つ以上のステップに分割することができる。例えば、1つのジョブがBDU22内に100万の記録を包含するバルクファイルをロードすると仮定する。ジョブは100万個のステップに分割でき、各々のステップは100万個の記録のうちの1つをロードする。標準的には、1ステップ内には多くの計算はない。従って1つのステップは、全ジョブについての実行時間に比べわずかな時間で実行可能である。ジョブは、障害の後連続的オペレーションを確実に行なうため、全てのステップの後にファイル位置を包含する変数を更新することを含め、充分な状態を維持することを担当する。周期的に、ただしステップの間で、JEP300は、完了したステップの結果を包含するトランザクションをコミットし、新しいトランザクションを開始する。1つのトランザクションは、完了したステップの結果がBDU22内にうまく書込まれ記憶された時点でコミットされる。JEP300が現行トランザクションをコミットする時間の間、ファイル位置を内含する実行中のジョブの状態が更新される。障害が発生した場合、ジョブは、回復手順において最後に記録された位置にファイルを置くための充分な情報を有することになる。
既存のジョブが、JEP300により新しいジョブが産生されることを要求する可能性もある。セーターの例における産生されたジョブは、衣服部門の月毎の総所得を更新すること及び青色セーターの在庫を更新することを内含する可能性がある。1つのジョブがJEP300によって産生された後、ジョブはUSP23内にロードされる。データベースの一貫性を維持するためには、ジョブJの実行に起因して産生された全てのジョブが同じトランザクション内で、その産生されたジョブが効果を出すようジョブJが意図しているコンテンションスペース内のステージングセルに対して付加されることになる。ステージングセル及びコンテンションスペースについては後述する。
USP23は、ジョブの流れを管理して、適切な時点での実行のためJEP300に対しそれを誘導する。この流れは、高い全体的システムのスループット及びデータ処理効率を達成し、同時に実行されるジョブが矛盾しないようにするべく管理される。並行プロセスを多数のプロセッサが実行している場合、USP23は、多数のプロセスにより一定の与えられたデータセット180内のオブジェクトに対する同時アクセスを回避しながら、できるかぎり数多くのプロセスを使用状態に保つことを担当する。矛盾のない並行実行を可能にするため、同じデータセット180にアクセスするジョブは、JEP300の1つに割当てられた特定のキュー184の中に置かれる。通常キューよりも多いデータセットが存在することから、一定の与えられたキュー184は、複数のデータセットにアクセスするジョブを包含する可能性がある。1つのジョブが割当てられるキューは、ジョブのコンテンションインデックスから計算される。例えば、Nをキューの数として、0〜N−1までの整数が各キューに割当てられると想定する。コンテンションインデックスQを伴うジョブが、割当てられた数をもつキューに割当てられることになる(QモジュロN)。こうして、比較的より小さい数のキューに対し、潜在的に多数のコンテンションインデックスをマッピングすることができる。
各キューは論理的に1つの列として見ることができる。その列内には、同じデータセット180にアクセスするジョブすなわち矛盾しうるジョブが存在する可能性がある。潜在的に矛盾するジョブに対し同じコンテンションインデックスを割当てると、それらは、単一のJEP300によって実行される一定の与えられたキュー184にマッピングされる。このようにして、ジョブは、シリアルに実行されることが保証され、従って、いかなる矛盾も発生し得ない。
一方、ジョブを生成するプロセスの効率を高めるために、USP23は同様に、各々が図1に全てのキューにわたる縞として例示されている行304の形に論理的に組織される。各々の行は、その行が1つのプロセスによってアクセスされていることを表示するためにロックされ得る行制御オブジェクトを有する。プロセスが、1本の行にジョブを付加することを望むとき、書込みロックが要求される。この行は、代替的には、実行のための行内のジョブを取出すことを望む場合にJEP300によってロックされた状態で読取られる可能性もある。ロックを用いたジョブの付加及び取出しのオペレーションについて、以下で記述する。充分な行が提供される場合、1つが利用可能な状態となるのを待つことなく、未ロック行を見い出すことが常に可能となる。
ジョブは、生成後一度に1本の行内へとロードされる。ジョブのプロジューサは、未ロック行を発見し、その行をロックし、ジョブをその行内にロードし、次にロックを解除しなければならない。行304内で、ジョブは、それぞれのコンテンションインデックスによって決定されたキューの中に置かれる。このようにして、充分な行が存在する限りにおいて全てのプロジューサが、矛盾をひき起こすことなく同時にキュー内にジョブを書き込むことができる。
いくつかの実施においては、USP23及びBDU22は、連合データベースと呼ばれるデータベース組織の一部を成す(Objectivity/DB Administration、リリース5、1998年2月、Objectivity Incorporated)ここで図2を参照すると、連合データベース10は、一定数のデータベース単位(2つの単位100及び110が示されている)を包含している。各々のデータベース単位は、一定数のコンテナ120、130及び140を有する。連合データベース10、データベース単位(100及び110)及びコンテナ(120、130及び140)は、オブジェクテビティ社(Objectivity Incorporated)から市販されているObjectivity/DB(登録商標)と呼ばれる分散型スケーラブルオブジェクトデータベースの基本的構成である。
連合データベース10は、Objectivity/DB(登録商標)の論理的記憶階層の中で最高のレベルである。連合データベース10は、図2では1つのエンティティとして現われているが、ネットワークを介して接続される異なる場所で多重のデータ記憶デバイスを横断して分散されていてもよい。
物理的には、連合データベース10は、連合データベースファイル(図示せず)として存在する。連合データベース10は、連合を構成する付加的なデータベース100、110のカタログ13と同様に、連合データベース10のためのスキーマ15を記憶するシステムデータベース12を包含する。連合データベース10には、例えばロックサーバープロセス(データベース内のオブジェクトのロッキングを調整するために Objectivity/DB(登録商標)のクライアントが接続するサービス)といった Objectivity/DB(登録商標)プロセス(図示せず)に対しそれを識別する一意的整数が割当てられる。
各々のデータベース100、110は、Objectivity/DB(登録商標)論理記憶階層内で2番目に高いレベルにある。データベース100が、小売りビジネスのための顧客住所データといったようなユーザーアプリケーションの持続性データを記憶する。データベース100は、物理的にはデータベースファイル(図示せず)によって表わされる。各々のデータベースは、正確に1つの連合データベースに付加され、その連合データベースのカタログ13内にリストアップされる。データベースファイル及びそれに付随する連合データベースファイルは、異なる機械の上に存在し得る。物理的ファイル名を有することに加えて、データベース100は、連合データベース10のシステムマネージャによって規定されるシステム名をも有する。データベース100のシステム名は、連合データベース10内の論理名である。
データベース100内のコンテナ120は、オブジェクトと呼ばれる持続性データの基本単位を保持している(例えば145)。コンテナ120はオブジェクトの物理的クラスタ化を決定する。コンテナ120はロッキングの基本単位でもある。コンテナ120内のいずれかのオブジェクトがロックされた時点で、ロックは全コンテナに適用され、コンテナ内の全てのオブジェクトを有効にロックする。
コンテナレベルの細分性は、ロック管理プロセスが、潜在的に何百万又は何十億のオブジェクトレベルのロックではなく比較的少ないコンテナレベルのロックを管理する必要しかないため、全体的性能のためになり得る。図2は、オブジェクトが別々のコンテナ内にクラスタ化されしかもなお互いに参照し合うことができるということを示している(148)。
例えば、図1及び図2のデータセット180は、一定数のBDUデータベース100を含むことができ、各々のBDUデータベース100は何万ものBDUコンテナ120を含むことができる。各々のBDUコンテナ120は、個人又はビジネス記録を保持するオブジェクト145ならびにオブジェクト間のリンク148を記憶する。
あるいは、オブジェクト145は、BDU22内のオブジェクトを新規作成する、削除する又は修正するといったような書込みオペレーションを実施するジョブを表わすことができる。書込みオペレーションを受理する(すなわちこれによる影響を受ける)BDUオブジェクトは、オブジェクト145と同じコンテンションインデックスを有していなくてはならない。一方、その活動の一部分として読取りオペレーションを実行するジョブを、任意のデータベースから読取ることが可能である。書込みオペレーションと矛盾することなく読取りオペレーションを管理するための機構は、Objectivity MROW1(多重読取り装置単一書込み装置)から容易に入手可能である。
図3は、システムデータベース12、BDU22及びUSP23を内含する連合データベース10の一実施態様を示す。USP23は、(n+1)個の論理列と(m+1)個の論理行をもつ行列として組織される。つねに矛盾を回避するためUSP23に必要とされる行及び列の数については後述する。
USP23の論理列及び対応するBDU22のデータセット180が1つのデータベース(201、202、…20n)を形成し、各々のデータベースがコンテンションスペース(211、212、…21n)を表わす。論理列の1つ、すなわち図3中の最も左側の列は、ルートデータベース24内に記憶されている。ルートデータベース24を表わすものを除く各々の論理列には、実行セル(EC)と呼ばれる1つの論理セルとステージングセル(SC)と呼ばれるm個の論理セルが内含されている。
USP23の論理行304は、その行の構成セルに対するアクセスを管理するための論理単位である。図3では、行304は、ステージングセルSC12、SC22…SCn2を保持している。
各々の論理セルは、実行セルであれステージングセルであれ、ジョブオブジェクトを保持する1つのコンテナである。ステージングセルは、JCP350が、新規作成された後のジョブを置く場所であり、また実行セルまで転送するためにJEP300がジョブを受理する場所でもある。実行セルは、準備完了状態のジョブ、実行中のジョブそして待機中のジョブを保持する。ステージングセルは、JCP350からロードされたジョブを保持する。
ルートデータベース24は、1つのジョブスケジューラ(JS)コンテナとm個の行コンテナ(R1、R2、…Rm)を内含する。各々の行コンテナは、その行の構成ステージングセルのリストを保持する行制御オブジェクト292を有する。行制御オブジェクト292が、その行の1つの書込みロック又は一定数の読取りロックのためのハンドルとして使用される。各々のコンテンションスペースのための構成セルのリストが、そのコンテンションスペースの実行セルコンテナ内に記憶されたコンテンションスペースオブジェクト291の中に保たれている。行制御オブジェクト292及びコンテンションスペースオブジェクト291の全てについての情報は、JSコンテナ内に保持されている。
データベース(例えば201)は、それぞれのプロセッサ(例えばプロセッサ321)によってアクセス可能であるデータ記憶デバイス(例えばディスク311)の中にある。好ましくは、各々の列データベースは別々のディスク上に記憶され、各プロセッサは、単一のJEP300のみを実行する。例えば、データベース201は、JEP300を実行するプロセッサ321によってアクセス可能なディスク311上に存在する。この配列は、ネットワーク通信量を低く保ち、ディスクスラッシングを低減させ、こうしてネットワークの待ち時間を改善し、スループットを増大させる。
ルートデータベース24内のコンテナは読取り又は書込み頻度が少ないことから、ルートデータベース24の物理的配置は、性能にとって非常に重要なことではない。
1対1のマッピングを用いて、すなわち1列につき1つのJEPの割合でUSP23の論理列内のジョブを処理するべくJEP300を割当てることが可能である。しかしながら、スケーラビリティ及びロードバランシングを可能にするべくその他のタイプのマッピングを実施することもできる。例えば、多数の列に対して1つのJEPを許容することにより、プロセッサ、プロセス又は列の数に関してUSP23のスケーラビリティを増強することができる。多数の列に対して1つのJEPという配置は、プロセッサの数が変わった場合に、USP内の列の数及びプロセッサあたりのJEPの数を同じままにすることができ、そのためUSP23により使用されるプロセッサの数をスケーリングするのに必要な努力が少なくてすむという利点をもつ。その上、同じJEP、同じプロセッサ上で実行中の多数のJEP又はその両方の組合せに割当てられた多数の列を横断してジョブロードを平衡させることができる。その一方で、1本の列に対して多数のJEPを可能にすることより、USP23の性能を改善させることができる。1本の列に対して多数のJEPを配置する場合、矛盾を防ぐため実行プロセスとして1つのJEPのみが指定され、その他のJEPは、実行をスピードアップするための補助(例えば予備取出しジョブ)を提供するにすぎない。
全てのコンテンションを避け、ロックされた行上でいかなるプロセスも待機していないようにするためには、C個のJEPとP個のJCPをもつUSPについて少なくともC+P本の行とC本の列が必要とされる。一定の与えられた時点で利用可能なショブを各JEPが確実に有するようにするためには、C本の列が必要とされる。中に新しいジョブをロードするために任意の与えられた時点で利用可能な行を全てのJCP及び全てのJEPが発見できるような形で、C+P本の行が必要とされる。JSコンテナ、行コンテナ及び列コンテナを考慮に入れると、コンテンションを回避しロック上の待機をなくするために必要とされる合計コンテナ数は(C+P+1)(C+1)である。新しいジョブをロードするためにいかなるプロセスもロック上で待機する必要がないことから、新しいジョブは、それらが生成又は産生されると直ちにUSP23によって受入れられる。
USP23は、Visual Works Smalltalk、Java又はC++を含む一定数のコンピュータ言語で実施できる。実施例には、各機械が物理的ディスク及びプロセッサを有している状態で、複数の機械を接続する中速度のネットワークが必要とされる。各機械のディスクは、その機械のプロセッサにとってアクセス可能なものであるUSP23の列を保持している。
USP23のオペレーションにおいて、JEP300は、USP23内でジョブを実行し次に削除する消費者プロセスを表わす。周期的にか又はJEPの実行セルがすぐに実行できるジョブを全くもたなくなった時点のいずれかで、JEP300は、行のランダム順列からラウンドロビンスキームを用いて行を走査する。選択された行をロックできない場合、行のうちの1つの上で読取りロックが獲得されるまで順列により選択された次の行が試みられる。読取りロックが獲得された後、JEP300は、指定されたコンテンションスペース内でロックされた行に位置づけされたステージングセル内の全てのジョブを取出し、ジョブを実行セルにコピーし、そのステージングセルからそのジョブを削除する。次にJEP300は、読取りロックを解除し、一度に1つのジョブを実行し始める。同じトランザクション内で1つのジョブを実行した後、JEP300は実行セルからジョブを削除する。
ジョブ実行中に、JEP300は、そのジョブが、何らかの新しいジョブの産生を必要とするか否かを見極めるためジョブと共に運ばれる情報を使用する。JEP300によって産生された新しいジョブがある場合、それらは、書込みロックと共にJEPが獲得した行のステージングセル内に記憶される。ステージングセルは、新しいジョブのコンテンションインデックスによって特定されたコンテンションスペース内に位置づけされている。
1つの行制御オブジェクト(例えば292)は各々の読取りロックが別々のコンテンションスペース内で異なる消費者により獲得される限りにおいて、同時に多数の消費者により獲得される多数の読取りロックを有する可能性がある。しかしながら、行制御オブジェクト292は、一度に1つの書込みロックしか許容せず、これは省略時 Objectivity/DB(登録商標)を通して達成される。1本の行上の書込みロックは、同時の読取り及び書込みがデータの非一貫性を作り出す可能性があるために、同一の行上に読取りロックを得ようとする試みをすべて排除する。同様にして、1本の行上の1つ以上の読取りロックの存在は、同じ行上の書込みロックの獲得を妨げる。
JEP300は、1つのトランザクションをコミットするとき、キャッシュメモリー又はディスクのような持続性メモリに対し、ジョブ実行の結果を書き戻す。ジョブ実行のトランザクションは、実行されたステップの数又は実行時間の長さといったような、予め定められた規準に基づいて定義される。予め定められた規準を満たす場合、例えば、トランザクションの開始から10秒が経過したか又は1つ以上のジョブの500のステップが実行された時点で、JEP300は1つのトランザクションをコミットする。トランザクションは、ジョブが短かい場合、多数のジョブの実行を内含することができる。例えば、1つのトランザクションは、1つのジョブの後半部分、完全な10個のジョブ、及びもう1つのジョブの前半部分を内含しているかもしれない。
消費者プロセスのオペレーションには一般に以下のものが含まれる。
1.JEP300が実行セルから1つのジョブを選択しそれに#start:メッセージを送ることから始める。ジョブは、1つのオブジェクトである第1の記憶をJEP300に戻すことにより応答する。第1の記憶は、その後ジョブへと戻されることになる。第1の記憶は過渡的であり(すなわち、RAM内にのみ保持され、連合データベース内のどこにも記憶されない)、JEP300は自動的にそれを追跡することを続ける。
2.周期的に、JEP300は、#atEnd:メッセージを送り現行記憶をジョブに戻すことによりそれが終わったか否かをジョブに問い合わせる。ジョブが「真」のインジケータを戻した場合、以下で説明するように終了メッセージが送られる。
3.ジョブが「真」のインジケータを戻さない場合、JEP300はジョブに#step:withScheduler:メッセージを送り、ジョブに現行の記憶及びJSコンテナ内に記憶された情報を渡す。ジョブは、第2の記憶(第1の記憶と同じオブジェクトである可能性もある)を戻す。JSコンテナ内に記憶された情報といったような管理情報もジョブに対し渡される。この情報は、ジョブがより多くのジョブの産生を必要とする場合に使用される。
4.次にJEP300は、例えば、最後のトランザクションがコミットされてから10秒が経過したか否かに応じて、ショブのトランザクションをコミットすべきか否かを決定する。その後、JEP300はそれが終わったか否かをジョブに再び問い合わせる。
5.ショブがひとたび「真」インジケータを戻した時点で、JEP300はジョブに#finish:メッセージを送り、ジョブに現行の記憶を渡す。次にJEP300は、ジョブを削除する。
6.JEP300は、実行セル内の次のジョブに着手する。実行セル内でいかなるジョブも実行できる状態にない場合、JEP300は新しいジョブのためその列内の行を走査する。
ジョブの実行は、JEPの障害によって中断され得、ジョブは部分的にしか実行されなくなる。しかしながら、コンテンションスペースオブジェクト291は、トランザクションがコミットされる毎にその実行セルコンテナ内の現行の実行ジョブの状態を記憶することから、ジョブの状態は、少なくとも最近コミットされたトランザクションの時点まで回復され得る。
回復手順は、障害あるものと交換するため新しいJEPを開始させること、そして次に部分的に実行されたジョブに再開するよう知らせることを内含する。回復手順は、外部状態が存在する場合、それをジョブがリセットすることを可能にする。回復手順は一般に以下の通りである:
1.ジョブに、#restart:メッセージを送る。ジョブは、そのジョブの実行を続行する上で使用するべく、新しいJEPのための記憶を戻す。
2.前節で記述したようなジョブ実行手順のステップ2で続行する。
ジョブをUSP23に付加するため、ジョブ生成プロセスは、書込みロックが1つの行上で首尾よく獲得されるまで、行のランダム順列からラウンドロビンスキームを用いて行を走査する。ジョブ生成プロセスは、JCP350であっても、新しいジョブを産生していくJEP300であってもよい。ジョブ生成プロセスは、そのジョブ及び同時にロードされているその他のジョブがその行内のステージングセル内に置かれる間、ジョブ生成トランザクションが終るまで、書込みロックを保持する。ジョブ生成トランザクションは、ジョブ消費者のトランザクションと同様に定義づけされ得る。トランザクションが完了した後、ジョブ生成プロセスは書込みロックを解除し、ジョブは、行上の読取りロックを用いてそれぞれのJEP300による実行のため選択され得る。このようにして、USP23内にジョブを付加するオペレーションには一般に以下のものが含まれる。
1.その行の行制御オブジェクト292上にある書込みロックを獲得することにより、1本の行上の書込みロックを獲得する。
2.ジョブのコンテンションインデックスに従って、ロックされた行の適切なセルにジョブを付加する。
3.書込みロックを解除する。
「SampleUSP」という名前でUSPを新規作成するためには、以下の手順を用いることができる。
[外1]
手順は、「UpdateStreamProcessor SampleUSP root」、「UpdateStreamProcessor SampleUSP contention space1」、...「UpdateStreamProcessor SampleUSP contention space10」という名前の11のデータベースを新規作成する。ルートデータベースは、1つのJSコンテナと、10+4=14の行の各々について1つずつの行コンテナを有する。その他の10個のデータベースの各々は、好ましくは、そのコンテンションスペースを処理するべく割当てられたプロセッサ又はその近くにあるディスク上に記憶されたコンテンションスペースを表わす。
以下の例は、SampleUSPと名付けられたUSPの位置を特定しUSPに対するハンドルを受けとるためのアプリケーションプログラムの命令を示す。例えばアプリケーションプログラムは、図1でトランザクションシステム192内に記憶されたものであってよい。
[外2]
以上の機能は、1つのトランザクション内で呼出しされなくてはならない。ひとたびハンドルが受理された時点で、アプリケーションプログラムはさらに、新しいジョブをスケジュールし既存のジョブを実行するためUSPのプロセスを命令することができる。
以下の命令は、行をロックしその行の中に1つのジョブを書込むためJCP350をトリガーする。
[外3]
currentOutputRowは、未ロック行を発見する1つの機能であり、この機能は、ジョブ生成トランザクション内で呼出される。新しいトランザクション内のCurrentOutputRowに対する第1の要求のみがJCP350にもう1つの未ロック行を発見させる。反復的要求は、JCP350に同じ行を戻させることになる。
時として、ジョブは、結果の正しさを確保するべく予め定められた順序で実行されなくてはならない。ジョブ実行の予め定められた順序を強化する方法は、同期化と呼ばれる。市販のデータベースシステムでは、例えば、人物の間に関係があるかもしれず、これらの人物と付随するオブジェクトは互いに属性を介して参照し合うことができる。1つの記録をもう1つの記録又は人物に関係づける属性、関係及びリンクを更新する場合、ジョブ実行の適正な順序が求められる。そうでなければ、データベースシステムの無欠性は破壊され、データの一貫性は失なわれる可能性がある。
1つのジョブは、共に同期化のために使用される定数分数及びタグを有する。同期化に参加する1つのジョブは、同じ同期化に参加するその他のジョブの全てが実行セル内に到着した時点で初めて実行され得る。同じ同期化に参加するジョブは、そのジョブのタグによって識別される同期グループを形成する。ジョブのタグがニル(無)である場合、それは、そのジョブがいかなる同期化にも参加しないことを意味する。ジョブのタグがニルでない場合、それは、同じタグをもつその他のジョブと共にまとめられる。
1つのジョブの定数分数は、同期化における定足数の割合を表わす。例えば、5つのジョブが同期化される必要がある場合、各々のジョブには定数分数値1/5に割当てられる。実行セル内の同じタグをもつジョブの合計分数が1に達した時点で、これらのジョブは過渡的メモリー内のスモールトーク辞書から実行セル内に記憶された実行準備完了リストまで、大量に移動させられる。辞書は、実行セル内で待機するジョブのリストを保持している。同期グループのジョブを容易に識別できるように、待機中のジョブはそのそれぞれのタグによってインデクシングされる。待機中のジョブは、そのそれぞれの同期グループ内のいくつかのジョブが実行セル内に到着していない場合、まだ準備完了とはならない。
ゼロの定数分数をもつジョブは無効である。同期化される必要のあるジョブグループの合計定数分数が1より大きい場合、エラーが起こる。
同期グループのジョブは、同じコンテンションスペース内で実行されなくてはならない。ある一定の順序で、異なるコンテンションスペース内のジョブが実行される必要がある場合には、一定の与えられたコンテンションスペース内の定数分数を1までパッドするためトークンジョブを生成することができる。例えば、ジョブ1が、全て異なるコンテンションスペース内にあるジョブ2及び3を新規作成すると想定する。さらに、ジョブ3はジョブ2が完了した後にのみ実行されなければならないと想定してみよう。ジョブ3が新規作成された時点で、それには1/2という定数分数と、生成された一意的タグが与えられる。ジョブ2が新規作成された時、それは全くタグをもたないが、ジョブ3のタグが何であるかはわかっている。ジョブ2が実行するとき、それが最後に行なうのは、ジョブ3と同じタグと1/2の定数分数をもつトークンジョブ3aを新規作成することである。ジョブ3及び3aが両方共到着した時点で初めて、それらは実行できる。ここでジョブ3aは、1という定数分数を達成しジョブ3が実行できるようにするトリガーとして作用すること以外何も行なわない可能性がある、ということに留意されたい。
もう1つの例として、その他のジョブを生成する数多くのステップを伴う非常に長い実行中のジョブを考えてみる。例えば、主要ジョブが完了してしまうまでは、これらの産生されたジョブのいずれも実行してほしくないと我々が考えているとしよう。トランザクションは、主要ジョブのステップ間で何度もコミットされ得、こうして、産生されたジョブはその標的コンテンションスペースまで伝達され得るようになることから、我々は同期化を使用しなければならない。我々は各々の産生されたジョブに可能な限り最小の定数分数(2-32)を与え、どれほどのジョブが各々のコンテンションスペースに行ったかを記録することができる。主要ジョブの最後のステップで、我々は、我々がそのコンテンションスペースに送ったジョブの定数分数の合計を1から引いたものである定数分数を用いて、我々がいずれかのジョブを送った各々のコンテンションスペースに対しダミートリガージョブを送ることができる。こうして、これらのトリガージョブが送られた時点(これは主要ジョブが完了した時点でしか起こらない)でのみ、以前に産生されたジョブは実行を開始することができる。
1つのジョブが支持するタグは、同期グループの一部としてそのジョブを識別する一意的整数である。JEP300は、タグ整数を同期グループにマッピングするためにRAM内のアソシエイティブ構造を使用する。JEP300は、定足数を決定するために同じタグをもつジョブを一緒にまとめる。ジョブは、それらが実行されるまで制限された時間だけデータベース内に存在するにすぎないことから、USP23内の任意の既存の同期グループについて一意的な1つの整数を生成する目的で、通常は1つの巡回64ビット計数器で充分である。計数器上のコンテンションを避けるため、各々のコンテンションスペースオブジェクト291は、対応するJEP300によって産生されるジョブのためにその独自の64ビット計数器を維持する。各々の行制御オブジェクト292は、JCP350によって新規作成されたタグ付きジョブを構築するための計数器も保持している。タグの一意性を確保するためにジョブを保持するコンテナの列数又は行数を、取込むことが可能である。産生されたジョブのタグのための整数を生成するための1つの実施では、N本の列をもつUSPの列の各々に対し0からN−1までの数字が割り当てられる。ジョブのタグ整数は、計数器の値をNで乗じ次にジョブを保持するコンテナの割当てられた列番号を加えることによって生成できる。JCP350により新規作成されるジョブについてタグを生成するためにも類似のアプローチを使用することができる。行制御オブジェクト291及びコンテンションスペースオブジェクト292から生成された同期グループを区別するには、正負符号のついた整数を使用してもよい。
タグを作成する必要がある場合、JCP350又はJEP300は、行制御オブジェクト292又はコンテンションスペースオブジェクト291に対しそれぞれメッセージ#nextUniqueInteger を送る。タグが生成されている時間の間、この計数器上でのコンテンションを防ぐため行制御オブジェクト292又はコンテンションスペースオブジェクト291上の同じトランザクション内で書込みロックが獲得される(そして標準的にはすでに先行する要求により獲得されている)。
タグを生成するために行制御オブジェクト292に送られる命令は、以下の通りである。
[外4]
タグを生成するためにコンテンションスペースオブジェクト291に送られる命令は、以下の通りである。
[外5]
定数分数とタグを使用して、ジョブ実行の正しい順序が保証される。例えば、コンテンションスペース#1内のジョブJ1がジョブJ2及びJ3を新規作成すると想定する。これらのジョブは、異なるコンテンションスペース(例えば、それぞれコンテンションスペース#2及び#3)内で実行する。J2が終了した時点で、それはジョブJ4を新規作成する。同様に、J3はJ5を新規作成する。J4及びJ5は、J1が実行したコンテンションスペースに割当てられる。J4及びJ5は互いに同じタグ整数をもち、各々が1/2という定数分数を有する。こうして、J4がまず最初にコンテンションスペース#1内に到着したならば、それはJ5も到着するまで実行され得ない。同様に、J5が最初に到着したとしても、それは、J4が到着するのを待って実行しなければならない。
J4及びJ5は同じタグを有していなければならないが、そのタグは包括的に一意的でなければならない。従って一意的整数を(例えば次の一意的整数について現行の出力行にたずねることによって)割当てるのはJ1の責任である。J1はJ2及びJ3に、この整数が何であるかを告げる(ここで、J2及びJ3は同期化される必要がないため独自のタグを全くもたないということに留意されたい)。J2がJ4を新規作成した時点で、それはJ4のタグをこの整数にセットする。同様に、J3はJ5のタグをこの同じ整数にセットする。J2及びJ3は、J2及びJ3が含む残りのデータから明らかでない場合にJ4及びJ5をどのコンテンションスペースに送るべきかについての情報を包含していなけれはならないかもしれない。
一対の同期ジョブを新規作成するべくJCP350をアプリケーションプログラムがトリガーするためのコード例が、以下に示されている。このコード中、ジョブ1及びジョブ2には同じコンテンションインデックス、同じタグそして合計1となる異なる定数分数が割当てられている。両方のジョブ共、そのいずれかが実行され得る前に、割当てられたコンテンションスペースの実行セル内に到着しなければならない。
[外6]
同期ジョブグループが指定された実行セル内に到着した後、JEP300が、ジョブグループを実行する前に、ジョブ折畳み手順が起こるかもしれない。このジョブ折畳み手順は多数のジョブを単一のジョブへと減少させ、こうして冗長なジョブを除去し、反復されたジョブを単純化させる。同期ジョブグループがいつでも実行できる状態になった時点で、JEP300は順番にこれらのジョブの各々に対し#collapseJobs:メッセージを送り、ジョブコレクションを引き数として渡す。ジョブの1つがニルの代りに1つのジョブで応答した場合、このジョブが、全グループの代わりに使用されることになる。このジョブは標準的に、オリジナルのジョブグループ内で発見される全ての情報を包含する。新しいジョブの実行結果は、同期グループ内の全てのジョブの組合せ結果と等価である。例えば、N回の「計数器を1だけ増分する」というオペレーションは「計数器をNだけ増加する」へと折畳みされ得る。
同期ジョブグループ及びジョブ折畳みの使用例について以下で記述する。USP23は、一定の与えられた記録とBDU22内に記憶された記録との間に整合が存在するか否かを見極めるために、BDU22内の全ての記録を処理するロードジョブを実行することができる。例えば、一定の与えられた記録は、顧客ジョン(John)の新しい住所を含む新しい記録であり得る。ロードジョブは、一定数の整合ジョブを産生し、整合ジョブの各々は、一定の与えられた記録と記憶された記録との間で、誕生日、氏名、社会保険番号といったような特定の整合属性又は属性の組合せを比較する。
整合ジョブは、どの記録をそれが表わしているか、ならびに記録のためにどれほどの整合ジョブが作り出されたかを知っている。整合ジョブは、一定の与えられた記録と整合する対応する記憶された記録を見い出した時点で、各々がこれらの記録のうちの1つを保持する複数のジョブを新規作成し、整合を開始したコンテンションスペースまでそれらを戻す。各々の新しいジョブは、Mを整合ジョブの数としRをこの整合ジョブが発見した記録の数として、1/(M*R)である定数分数を有する。ここで、任意の整合ジョブからの応答の定数分数の合計が1/Mに等しいという点に留意されたい。いかなる整合記録も発見されなかった場合、定数分数1/Mで、これを表示するため特殊なダミージョブが送られなくてはならない。
顧客ジョンの例においては、整合ジョブは記憶されたジョンの記録の全てに言及する応答ジョブを生成した。これらの応答ジョブの全てがオリジナルのコンテンションスペースに戻った時点でのみ、これらを処理することが可能である。これは正確には、定数分数の合計が1に等しくなるときである。この時点で、整合応答ジョブを、整合する記録の完全なリストをもつ単一ジョブへと折畳むことができる。このデータは、必要に応じて分析及び併合でき、次に、変更された住所を収容するために修飾される必要のある各々の記録に対して更新ジョブを送ることができる。
タスクは、タスクの実行の結果として産生された全てのジョブが完了した後、肯定応答を送ることができるようにするためジョブの同期化を使用する。産生されたジョブは全て、そのタスクのコンテンションスペース;一意的タグ及び、一定の与えられたジョブによりその他のジョブの中に含まれたその他の分数の全てに対して付加された時点で合計で産生ジョブの分数となるような分数を支持している。タスクによって産生されたジョブの場合、それらの分数は合計で1となる。これらの分数を生成する迅速な方法は、産生されつつあるジョブの数で1を除したものをとり、これに産生ジョブの分数を乗じ、タスクの分数が1となると仮定されている産生されたジョブの各々の中で、結果として得た分数を使用することである。このスキームは、最終的ジョブ(肯定応答以外の作業を行なうのに何らかのさらなるジョブを産生する必要のないジョブ)を横断した全ての分数の和が合計で1となるようにする。最終的ジョブは、記録されたコンテンションスペース、タグ及び定数分数としての分数を伴う肯定応答ジョブを産生する。全ての肯定応答ジョブがそのタスクのコンテンションスペースに到達した時点で、これらは折畳みされ実行され、アプリケーションプログラムに対し肯定応答を送らせる。
その他の実施が、請求項の範囲内に入るものである。
例えば、別々の実行セルを使用する代りに、同期実行を必要としないジョブをステージングセルから直接実行することが可能である。しかしながら、同期化されたジョブは、その全てが同期グループとして実行され共に削除され得るような形で、なおも実行のために実行セルまで移動されなくてはならなくなる。
ステージングセルから直接のジョブ実行を容易にするため、各々のステージングセルは実行されるべく待機しているステージングセル内のジョブの数を表示する計数器を有している。計数器は、計数器の値が232−1に達した時点で0まで循環する32ビットの計数器であり得る。JCP350がステージングセル内に新しいジョブを付加した時点で、ステージングセル内の計数器は増分される。ジョブの付加及び計数器の更新の両方が、同じトランザクション内で行なわれる。
各々の実行セルは、それぞれのステージングセルのための完了したジョブの数を表示する類似の32ビットの計数器も有する。JEP300が1つのジョブ実行を完了した時点で、実行セル内の付随する計数器は、MROW書込みで増分される。MROWセマンティクスにより、計数器は単一の書込み装置及び多数の読取り装置によって同時にアクセスされ得ることになる。JCP350は、周期的に、MROW読取りで実行セル内の計数器を検査する。計数器の値は、それぞれのステージングセル内でいくつのジョブを削除できるかを見極めるために、JCP350によって使用される。
JEP300が新しいジョブの実行が必要となった時点で、JEPは、計数器がその最大値に達した時点で計数器はゼロまでラップできるということを考慮に入れて、計数器値が実行セルの計数器の値よりも大きいステージングセル内の全てのジョブを読みとる。(計数値−もう1つの値)モジュロ最大サイズ<(最大サイズ/2)である場合、計数器の値はもう1つの値よりも大きいものとみなされる。例えば、2つの4ビット計数器の値を比較する場合に、計数器の値は9であり、もう1つの値は7であると想定する。9−7=2、2モジュロ16=2であり、2は(16/8)より小さいことから、9は7よりも大きい。この減算もラップする。すなわち例えば(0−1)が計数器の最大値に等しい。JEP300のための作業負荷は、JEPがステージングセルを修正する必要が決してないことから減少する。
ある種の実施態様においては、USPは図1及び図3に示されている行列構造を持ちさえしない。その代り、USPはジョブデータベース及びTCP/IPソケットを介して通信するそのそれぞれのプロセスを含む。この実施態様においては、行の概念が存在しないことから、ロッキングオペレーションはもはや必要とされない。図3Aを参照すると、USP27には、JEPとJCPが内含されており、その各々は、プロセスを実行する同じプロセッサのメモリー内にあるジョブリスト(25)を有する。JCPのジョブデータベース26は、JEPに送られるジョブのバックアップコピーを記憶する。JEPのジョブリスト25は、実行されるべく待機しているジョブを追跡する。JCPが1つのジョブを新規作成した時点で、ジョブのコピーがバックアップとしてJCPのジョブデータベース26内にロードされる。JCPは、ジョブのコンテンションインデックスによってそのコンテンションスペースが特定されている適切なJEPまでTCP/IPソケットを介してジョブを伝送する。JEPはジョブを受理した後、一時的にそのジョブを、実行待機中のそのジョブリスト25に付加する。
TCP/IPソケットというのは、アプリケーションプログラムがTCP/IPメッセージをネットワーク上で送受信することができるようにするソフトウェアエンティティである。TCP/IPソケットを使用すると、ジョブをTCP/IPメッセージとして送受信でき、こうしてシステムのプログラマからネットワークのディテールが隠される。
各々のJCPは、各JEPへのソケット接続を有しており、それを通して、そのJEPによって実行されなくてはならないジョブを伝送することができる。特定のJEPを目的として特定のJCPからのジョブは全て同じソケット接続を通して伝送され、連続的ジョブのID番号、モジュロ232が割当てられる。
USP27は、Objectivity/DB(登録商標)によって実施される「自律区画化」の概念を利用する。自律区画化は、基本的に、連合データベースのデータベースサブセットである。各データベースは、正確に1つの自律区画に属する。USPのこの変形態様においては、各々のプロセスはその独自の区画内で動作できる。データベース書込みは、その付随する実行プロセスによって制御されるデータベースに局所的なものとして制約され得、こうして、ネットワーク通信量は大幅に低減され、プロセッサが回復されるまであらゆるプロセッサの故障が安全に隔離されることになる。ネットワーク通信量の減少の結果、自律区画は同様に、遠隔した地理的サイトに広がる広域ネットワーク(WAN)上での展開の望ましくない効果も低減される。この望ましくない効果としては、ローカルエリアネットワーク(LAN)と比べてデータ伝送コストが高いこと及び通信リンクの予想故障率が高いことが含まれる。ネットワーク通信量が低減されることから、自律区画はWAN上の展開のためのコストを低下させるのみならず、伝送の信頼性に対する要求も少なくする。
JCPとJEPとの間のTCP/IPソケット接続は、「データグラム」ではなくむしろ「ストリーム」種のものである。「ストリーム」種のための根底にあるネットワークプロトコルは、必要に応じて誤り訂正及び再伝送を内含するメッセージの送達を確保している。個々のIPパケットは、ゼロ以上の回数、任意の順序で物理的ネットワークアダプタに到着し、任意に折畳みされる。「ストリーム」ソケット実施は、これらのパケットを正しく順序づけし直し、誤伝送されたパケットの再伝送を要求し、冗長なパケットを放棄することを担当する。パケットの伝送が適正な時間又は努力(標準的には数秒)の量内で達成されず肯定応答され得ない場合、プロトコルは単純に、クライアント(すなわちJCP及びJEP)に対しそのソケットが接続解除されたことを通知することになる。ソケットが接続解除された場合、クライアントは周期的に、接続解除されたソケットを再接続することを試みることになる。JEPは、再接続を試みる一方で、接続されたソケットから到着するジョブを処理し続けることになる。こうして、ジョブ処理は、故障したノード又はネットワークリンクからの回復中でさえ続行される。
標準的なネットワーク上のパケットサイズは、長さが数キロバイトのものである。固定サイズのパケットについては、パケットを伝送するオーバーヘッドが固定される。ジョブのサイズは通常、パケットのサイズよりも短かいことから、単一のパケットとして各ジョブを伝送するのは効率の悪いことであろう。従って、伝送の前に、ジョブは、そのサイズがバケットサイズに等しいバッファの中に書き込まれる。伝送プロセスは可能なかぎり多くのジョブを各バッファ内にパックし、無駄になるネットワーク通信量を低減するべく1つのパケット内で全バッファを伝送させる。
場合によっては、ほぼ空のパケットをなおも伝送する必要がある。そうでなければ、USPが静止状態となった場合に、最終のジョブが決して伝送されない可能性がある。このようにして、我々は、パケット内で送られる前にどれほど長くデータがバッファ内にとどまり得るのかについての限界をセットする。例えば、最初のジョブがバッファ内に書込まれてから10秒以上が経過した場合、バッファはソケットに対しフラッシュされ、パケットを強制的に物理的に送らせる。一方、それをバッファ内の最後のジョブとの関係においてタイミングした場合、9秒毎に到着するとぎれがちなジョブは、その一部が長時間伝送されるのを待っていたという事実にも関わらず、バッファが数分間伝送されないように保つ可能性がある。より少ない待ち時間を必要とする環境内でUSPが使用される場合には、時間的限界を低減させることができる。
故障が発生した場合でさえジョブが確実に実行されるようにするため、コミットされたジョブは常に、ソケットを介してJEPに伝送される前にJCPのジョブデータベース26に書き込まれる。ジョブがJEPによって受信された時点で、我々は、ジョブがすでにJCPのデータベースにコミットされたことがわかる。故障の場合、JCPはそのジョブデータベース26を走査し、まだ実行されていない可能性のあるジョブを各JEPに再伝送することになる。JEPは、ジョブがすでに受信され実行されたことを表わすIDをもつジョブを単純に無視する。
JCPのジョブデータベースが勝手に大きくならないようにするため、各JEPは、1つのトランザクションをコミットする毎にJCP1つあたり1つの番号という割合で最近完了したジョブのID番号を記録する責任を負う。これらのジョブID番号は、RAM計数器によって計数され、回復中に、どのジョブがすでに実行され無視できるかを告げるのに用いられる。JEPはまた、各々のJCPに対して、そのJCPについてのRAM計数器値を含む削除メッセージを周期的に伝送する。JCPは、削除メッセージを受信した時点で、ラップ演算を用いて自由にメッセージ内のID以下のIDですべてのジョブを削除することができる(すなわち、そのIDがメッセージ内のIDに等しいか、そのメッセージ内のIDより下231以内にあるか又はメッセージ内のIDより231より大きい全てのジョブを削除することができる)。
ジョブ削除メッセージは、実行されなかったジョブのIDを支持することができない。ジョブが同期化されていない場合、ジョブは完全に実行されコミットされてしまわなくてはならない。ジョブが同期化されたジョブである場合、JEP内の情報の複製が必要とされる。同期化されたジョブのIDと共にジョブ削除メッセージを伝送するに先立ち、JEPはジョブデータベース25内にジョブのコピーを記憶しそれをコミットする。同期ジョブのコピーを記憶することは、故障の際の回復にとって必要である。そうでなければ、ジョブの持続的記録は全くなくなる。ジョブ同期化においてすでに記述したRAM内のアソシエティブ構造は、削除メッセージ内で伝送されたIDをもつ同期ジョブを含め、そのタグを伴う同期グループ内のジョブリストに対する各同期化タグからのマッピングの記録を行なう。回復時点でアソシエティブ構造はジョブデータベース25内のジョブから再構築される。
グループの合計定数分数が1に達した時点でそのグループには、単一ジョブへと折畳みする機会が与えられる。折畳みが発生した場合、そのグループのジョブはデータベース及びアソシエティブ構造から削除され、単一の置換ジョブが単一のトランザクション内のグループの代りに記憶される。単一のジョブは、定数分数が1である単一のメンバーをもつ同期グループとして扱われる。
同期グループが複数のオリジナルジョブから成るか又は折畳みにより新規作成された1つの単一ジョブから成るかに関わらず、グループがいつでも実行できる状態となった時点で、グループのタグは記録され、ジョブの実行が始まる。グループ内の1つのジョブが完了した時点でそのジョブはJEPのジョブのデータベース25から削除され、グループ内の次のジョブが開始される。グループの実行の途中でトランザクションをコミットすること(例えばトランザクションの持続時間を制限するため)が必要となった場合には、JEPは、グループのタグならびに実行中のジョブに対するポインタを記録することになる。コミットの間にクラッシュが発生した場合、グループの残りのジョブは、その他のあらゆるジョブの前に実行されることになる。グループの全てのジョブが完了した後、任意のソケット接続を介した次の入ジョブが処理される。
各々のJCP/JEP対は、その伝達されたジョブのための連続するID番号を使用すること、かつ、削除がジョブの伝送と同じ順序で起こることから、JEPは、各メッセージが1ブロックのジョブの削除を要求している複数の削除メッセージの一部分のみを安全に伝送することができる。JCPは、ジョブ削除メッセージを受信した時点で、伝送されたID以下のIDをもつ全てのジョブを(上述のようなラップ演算を用いて)削除する。ジョブ削除メッセージの数を低減させるためには、JEPは、削除メッセージのIDが予め定められた数の倍数(例えば1000)と交差する場合又は削除が予め定められたもの以上の長さの時間(例えば10秒)だけ前に起こりその時間内にJCPから(又はいずれかのJCPから)いかなる新しいジョブも到着しなかった場合のいずれかの場合にのみ、JCPに対し削除メッセージを伝送する。
後者の条件がない場合、多くても数千個のジョブがJEP故障からの回復時点で各々のJCP/JEP対について再度伝送されなくてはならなくなる。後者の条件がある場合、JCPは、新しいジョブが全く到着しないときでさえ、そのジョブデータベース26内の完了したジョブを周期的に削除することができる。後者の条件における時間の長さは、回復オーバヘッド、削除オーバヘッド及び伝送コストの間の妥協である。時間が短かくなればなるほどJCPは完了したジョブをより頻繁に削除でき、従ってJEP故障の場合にさらに少ないジョブが再伝送されることになる。しかしながら、後者の条件下で時間的限界を10秒より短くすることは、JCPが実行しなければならなくなる削除トランザクションの数を増大させることになるため、恐らくやりがいのないことである。著しく小さい値では、JCPのジョブデータベース26内でジョブの削除を扱うCPU時間がわずかしか無駄にならなくなる。より大きい値が使用される場合、多数の新しいジョブが最終的に到着した時点でJCPがそのアイドル時間を浪費してしまっているかもしれず、そのときたとえ新しいジョブが準備完了していてもジョブの削除を実行するのに時間を費やさなくてはならなくなるという不利な状況が発生する可能性がある。
代替的な見通しとして、標準的な同期化されていないジョブJのライフサイクルを考えてみる:すなわち
いくつかの時点でJCP#1がジョブJを新規作成すると想定する。ジョブJは、それがコンテンションスペース#2内のデータを操作することから、コンテンションスペース#2で実行するように割当てされる。コンテンションスペース#2がJEP#2の制御下にあり、ジョブJには、JCP#1からJEP#2に送られた先行ジョブのID番号より1つ大きい一意的ID番号123が割当てられると仮定する。
次にJCP#1が1つのトランザクションをコミットした時点で、ジョブJのコピーがJCP#1のジョブのデータベース26に書込まれることになる。JCP#1の現行のID番号も同様に同じトランザクション内で書き込まれることになる。トランザクションがコミットされた直後に、Jは一連のバイトへと変換され、JEP#2行きのその他のジョブと共にバッファ内に書込まれる。そのバッファが満杯になったとき、バッファ内の全てのジョブは、JEP#2へと1つのパケット内で送られる。
JEP#2は場合によってそのJCP#1〜JEP#2ソケット接続からパケットを受信する。パケットは、1連のバイトから1連のジョブへと変換され、有効にJ及びその他のジョブを再構成する。ジョブはRAM内のキューへと移動させられ、ここでこれらはその他のソケットから到着するその他のジョブとインターリーブされる。インターリービングは、JCP#1から来るジョブの相対的順序を保存する。
Jがキュー内にある間にJEP#2が破損すると想定しよう。JEP#2が再ブートされ、ソケット接続は再確立される。JCP#1からの接続が再確立された時点で、JCP#1は、Jのコピーを含め、そのジョブデータベース26内の全てのジョブを再伝送する。Jの前に着いたジョブの一部はJEP#2により完了するまですでに実行されてしまっているかもしれない。これらのジョブは、JCP#1によりとにかく伝送されるが、JEP#2はそれらを無視する。JEP#2は、ジョブのIDが、ジョブ#2がそのジョブデータベース25内に記憶した、現在完了しているジョブID以下であるとき、そのジョブを無視することを知る。JがJEP#2により再度受信された時点で、それは、JCP#1を起点とするその他のジョブとの関係においてジョブID順序でキュー内に置かれる。
場合によっては、JEP#2はJをそのキューから除去し、それを実行する。JEP#2は、今JCP#1からのジョブ123(すなわちジョブJ)を実行したことを表わすRAM計数器を増分する。RAM計数器は1つのトランザクション中に何回も増分され得ることから、同じトランザクション中でJの前及びその後に数多くのジョブを実行することができる。
トランザクションがコミットされた時点で、RAM計数器の現行値が、BDUオブジェクト内の変更と合わせて、ジョブデータベース25に書込まれる。この動作により、各ジョブがBDUに正確に1回影響を与えることが保証される。すなわち、Jが1つのオブジェクト内で計数器を増分した場合、計数器は、Jのために1回だけ増分されることになる。
いくつかのある種のトランザクションの後、JCP#1からの現在完了したジョブ番号を表わすJEP#2のRAM計数器は1005に到達し、これは、削除メッセージを送るのに必要とされる1000という値よりも大きい。新しい計数器値はこのときジョブ削除メッセージ内でJCP#1に伝送し戻されることになる。
JCP#1は、ID=1005を伴う削除メッセージを受信した時点で、(以上で記述したラップ演算を用いて)1005以下のIDをもつそのデータベース内の全てのジョブを削除する。JのIDは、1005以下のものである123であるため、それは削除されることになる。この時点で約1000以上のジョブが削除されつつあること、そしてそれらのうちの多くが当初単一のトランザクション内で書き出されていたことから、削除には標準的に非常にわずかなジョブデータベース26のページをディスクに書き戻すことしか必要としない。このトランザクションがひとたびコミットすると、いずれのデータベース内にも又はいずれのプロセッサのメモリー内にもJの痕跡はもはや何もなくなる。
JCP#1とJEP#2との間に起こった唯一のネットワーク通信は、JCP#1からJEP#2へのジョブの伝送及びJEP#2からJCP#1への削除メッセージの伝送であった。JEP#2が最初の伝送の後に破損したことだけを理由として、ジョブJの伝送はこの例において2回起こった。削除メッセージは、1つのパケットで約1000のジョブを一掃した。
ネットワーク上で伝送される情報を圧縮することにより、ネットワーク通信量を減少させることができる。例えば、単純な圧縮スキームとしては、ジョブのサイズを低減させるものが考えられる。ジョブは1つのオブジェクトであり、そして各々のオブジェクトはそのオブジェクトの構造及び挙動を定義するあるクラスのインスタンスであることから、我々はジョブをクラス「ジョブ」の異なるサブクラスのインスタンスとして定義づけすることができる。ジョブは、クラス「住所」又はクラス「人物」のインスタンスを更新するために新規作成することができる。従って、ジョブクラスは、そのタスクが1つのオブジェクトクラスに向かって導かれているジョブを内含する。JCPが最初に1つのジョブクラスのインスタンスをバイトへと符号化した時点で、そのクラスの名前は、ジョブオブジェクトの符号化と共に伝送される。このとき、このクラスは遭遇したクラスのリストに付加され、一意的番号が与えられる。このクラスのインスタンスが次に伝送される時には、このクラスの一意的番号が代りに伝送される。こうして、圧縮スキームは、ジョブの伝送オーバーヘッドを有効に低減させる。
各JEPの効率を改善するためには、我々がOIDソーティングと呼ぶ技術を使用することができる。この技術では、ジョブが実行されるトランザクションの開始時点で、全ての利用可能なジョブはまず最初に、そのジョブによって修正されることになるオブジェクトがある場合その一意的オブジェクト識別子によりソートされる。1つのジョブを実行することによって多数のオブジェクトを修正できる場合には、任意に1つを選択することができる。1つのジョブが1つのオブジェクトを新規作成する場合には、新規オブジェクトを含むことになるコンテナの識別子がソーティングのために使用される。このとき、ジョブの実行はこのリストを通して順番に進行する。
ソートされたジョブリストが単一のトランザクション内で完全に実行されない可能性があるため、我々は、万一故障が発生した場合に、回復中に残りのジョブを再構築するためにオブジェクト内に充分な情報を記録しなければならない。この情報には、各々のジョブソースについて、リスト内のジョブの最初と最後のid番号が含まれる(ジョブには、そのジョブがそこから及びそこへと伝送されるJCP/JEP対に関してのみ一意的id番号が割当てられる)。こうして我々は、回復時点で正確に同じジョブリストを再構築することになるが、我々もまた1つのトランザクションをコミットする場合に常にこれらのジョブのうちのどれだけが実際に実行されたかを記録しなければならない。その情報は、故障からの完璧な回復を可能にする。故障したJEPの回復中、我々は、故障時点で実行中であったジョブのソートされたリストに参与するジョブを各JCPが少なくとも再伝送するのを待たなくてはならない。
ソートされた全部のジョブリストが完了した時点で、次に、実行されたジョブを提供した各JCPに対して、ジョブ削除メッセージを送ることができる。我々がリスト内のどこにいるかを告げる持続計数器がリストの出発点ではなく終点との関係におけるものである限りにおいて、この時点以前に削除メッセージを送ることもなお合理的である。そうでなければ、リスト内の早期ジョブの一部が削除された時点で、これらが回復時にJEPに対し再送されることはない。
ジョブによる影響を受けたオブジェクトの一意的オブジェクト識別子によりジョブをソートすることには、いくつかの理由がある:すなわち、オブジェクト識別子は、互いに数値的に近いオブジェクト識別子が互いに物理的にさらに近いオブジェクトを表わすことになるように1つのオブジェクトの物理的場所を符号化することから、トランザクション1回につきデータベースからのさらに少ないページしか検査/書込みされる必要がなくなる可能性があるからである。同じページへの多数の書込みが、単一の物理的書込みへと合わせて集約されることになる。トランザクション1回につきロックされる必要があるコンテナの数は少なくなるかもしれない。オブジェクト識別子の高いビットはコンテナを特定し、低いビットはそのコンテナ内のオブジェクトを特定する。コミット時に書込まれるページは、ディスク上で強い物理的近接性をもち、従ってシーク時間は短縮されることになる。
回復時点にジョブでの正確に同じリストが必ず生成されるようにするため、ソーティング規準は一貫してタイを中断しなくてはならない。こうして、更新されつつあるオブジェクトのオブジェクト識別子を考慮した後、発信JCP#及びジョブのid番号に基づいてさらにソートすることによってタイが中断されなくてはならない。この値の対は一意的であることが保証され、タイをはっきりと(任意に)中断するのに充分なものである。
1つのオブジェクトに対する各々の変更は潜在的に多くの作業を必要とする(例えば後述のようにオブジェクトを再インデクシングすること)可能性があることから、できればこの状況を避けたいと考えるかもしれない。従って1つのジョブの実行が求められた時点で、このジョブは、同じオブジェクトに影響を与えるジョブのリストを検査することができる(これらのジョブは、ソートされたリスト中で現行ジョブの後にくる)。このとき、これらのジョブによって表わされた変更は、一緒に単一の更新オペレーションの形に折畳みされ得、このオペレーションは、我々の例では、この変更セットについて再インデクシングが一度だけ起こることを可能にする。ジョブは、矛盾する変更を実行する順序を識別するため、該当する場合、タイムスタンプを指示することができる。
修正中のデータの場所に基づいてジョブを、順序づけする以外に、ジョブがいかに緊急に完了されなくてはならないかに基づいてジョブでの優先順を定めたい場合があるかもしれない。バッチジョブを完了させることに緊急性はないかもしれないが、ユーザーによって直接トリガーされるオブジェクト更新ジョブはおそらく、できる限り早く実行すべきである。このニーズを支援する基本的機構がいくつか存在する。
デッドラインベースのソフト実時間優先性スキームにおいては、各ジョブには1つの時刻が結びつけられている。ジョブがこの時刻までに完了していることが強く望まれる。残念なことに、これはOIDソーティングと干渉する。この矛盾を解決するために、以下のアルゴリズムが使用される。任意の時点で、JEPは、満了時間によってソートされたジョブのヒープを有する。ジョブ実行プロセスは、このヒープの最上要素を参照する。これは、我々が一時的に過負荷状態にある場合には、過去にあると考えられる最も早いデッドラインをもつジョブである。5秒より多く未来にあるジョブをポップしたか又は全てのジョブをポップしたかのいずれかが先に起こる時点まで、ジョブがヒープからポップされる。このとき、我々はこれらのジョブのOID順にソートし、1回のトランザクション内でこれらをできるかぎり多く実行させようと試みる。単一のトランザクション内でそれら全ての実行が終了しなかった場合(例えば、そのトランザクション内で10秒より長く経過し、10秒が構成上最長のトランザクション時間であるため)、我々は、トランザクションをコミットし、次のトランザクションでこれらのジョブの実行を続ける。
このスキームで完了したジョブの削除に対処するためには、同期化されたジョブについて既に記述した解決法を参照する。1つの同期化されたジョブは、コピーがそのJEPのデータベースにコミットされた時点で、「対処された」とみなされる。この時点で(又はその後一時置いた時点で)、JCPがそのジョブのそのコピーを削除できることを表示するメッセージでJCPに対し送り戻される。OIDソーティングされた実行(すなわちジョブid順にない実行)を支持するために、全ジョブのコピーを、ただ同期化されたものでなく、JEPのデータベースにコミットする必要がある。
図1を参照すると、データ処理センタ191内のBDU22は、数百万個のオブジェクトを含むことができる。BDU内で1つのオブジェクトの位置を特定するため、その場所又はその他の属性を含むそのオブジェクトについて情報が記憶され、並行(同時)処理環境内で効率良くアクセスするために配置されている。
例えば、保険会社のデータ処理センタ191の場合にはBDUオブジェクトの各々は、あるタイプの保険証券の下で保険を担保されている人物についての記録を表わすかもしれない。このタイプの保険証券の特長に変更がある場合、保険代理店はこのタイプの保険証券の下で保険を担保されている人々全ての位置を特定し、彼らにその変更について通知することを望む可能性がある。この人々の位置を効率良く特定するため、予めソートされたエンティティを含むファイルを使用することができる。予めソートされたエントリの各々は、1人の人物のオブジェクト及びその人物を識別する上で不可欠なその他の情報に対するポインタを内含する。例えば、保険代理店は、最後の名前によって予めソートされた一定の与えられたタイプの保険証券の下で保険にかかっている全ての人物についてのエントリをもつフイァルを使用することができる。
オブジェクトが新規作成され、削除され又は更新された時点で、ファイル内の対応するエントリは更新されなければならない。オブジェクトを新規作成し、削除し又は更新する全てのジョブが確実に一貫して対応する予めソートされたエントリを修正することになるようにするためには、ジョブは、ファイル、予めソートされたエントリ及びオブジェクトに対し必要な変更を行なうため共通の機構及び共通の書式に合意しなくてはならない。ファイル及び予めソートされたエントリの書式は、望ましいオブジェクトの探索及び位置特定を容易にするように設計されており、従って、予めソートされたエントリ内の情報の書式又はレイアウトは標準的にファイル内のその他のエントリと同じである。
共通機構は、対応するエントリを予めソートするために、オブジェクトのどの属性が使用されるか、エントリ内にどの情報が表示されるか及び1つのオブジェクト内の変更がいかにエントリへと伝搬すべきかを予め定義づけする。我々が共通機構と呼んでいるのは、非同期インデックスマネージャ(AIM)であり、ファイルとはインデックスであり、予めソートされたエントリとはインデックスエントリである。
数万(またはそれ以上)の同時データアクセスを可能にするデータベースシステムにおいては、アクセスの矛盾を回避しながらインデックスの無欠性を維持することが非常に重要である。AIMは、インデックスをいかに構造化し維持すべきかを定義する。インデックス内の変更を実行するタスクは、USPによってスケジュールされたジョブによって実施される。例えば、1つのオブジェクトが付加又は削除された時点で、該当するインデックス内の対応するインデックスエントリを付加又は削除するべく新しいジョブが産生される。同様にして、1つのオブジェクトを更新することがインデックスエントリの精度に対し効果をもつ場合、影響を受けたインデックスエントリを含む該当するインデックスを更新するべく、ジョブが産生される。
インデックスは、概念上、特定の書籍の位置を特定するため図書館で使用されるカードカタログに似ている。カードカタログは、各々1冊の書籍についての情報を含むインデックスカードを保持している。情報には書籍の簡単な要約ならびに、図書館内で書籍の位置を特定するのにカードカタログユーザーにとって必要なその他のデータが含まれている可能性がある。
書籍は、著者、題名又は主題といったよう多数の規準のうちのいずれか1つによって探索され得、書籍を表わすインデックスカードは、効率を良くするため探索規準によって分類される。一定の与えられたカタログは標準的には同じタイプの事物のコレクションのための情報を保持している。例えば、一つの書籍カタログ、定期刊行物カタログ又は音響媒体(テープ又はCD)カタログも存在し得る。カタログ内の全てのインデックスカードは、いかに情報が組織されているかに関して同じレイアウトを有する。例えば、書籍の題名は全てのインデックスカードの最上部にあり、著者名は題名の下にある。
BDU内でオブジェクトの位置を特定するために使用されるインデックスは、概念的にカードカタログに類似している。インデックスは、各々1つのオブジェクト(書籍)の小さな要約を含むインデックスエントリー(インデックスカード)のコレクションを内含している。1つのインデックス内で識別されたオブジェクトは同じタイプのもの、すなわちオブジェクト指向の専門用語では同じクラスのものである。インデックス内のインデックスエントリは、同じデータ構造を有する。インデックスエントリは、インデックスの意図されたアクセスパターン及びサイズに応じて、予め規定されたキーによってソーティング又はハッシングされ得る。
各々のインデックスは、システムアドミニストレータによって定義されうるキー及び非キー属性を有する。キー属性は、インデックスエントリをソーティング又はハッシングするために使用され、非キー属性は、キー属性と合わせてインデックスエントリ内に表示される。非キー属性の表示は、インデックスのユーザーがBDUからオブジェクトを検索する必要なくオブジェクトについてのある種の予め規定された情報を一覧できるようにする。図書館の例では、ISBNによってソートされたインデックスカードは、書籍の題名及び著者を内含する情報を含み得る。
図5は、インデックスエントリの図である。データベース内の全ての人物は、そのインデックスが、キー属性SSNによりソートされたそれぞれのインデックスエントリにより表わされる人物オブジェクトの1クラスを含んでいることを意味するPerson−SSNと呼ばれるインデックス内に対応する1つのインデックスエントリ40を有する。インデックスの各々のインデックスエントリはSSN、人物の氏名及び、それ自体人物の名前についてのより多くの情報を含む名前オブジェクト42を指す人物オブジェクト41に対するポインタを含有する。
インデックス及びインデックスエントリはディスク上及びメモリ内に記憶され得る。メモリ内にインデックスのコピーを記憶することによってインデックスアクセス時間を短縮し、従ってオブジェクトの位置を特定する処理速度を高めることができる。メモリ内のインデックスのコピーは、メモリー常駐(すなわちRAM常駐)探索構造(例えば2分探索樹又はハッシュテーブル)として実施される。ユーザーがBDUオブジェクトを更新するための要求を提出すると、結果としての更新ジョブは、BDUオブジェクトを更新するのみならず、付随するインデックスをも更新する。探索構造は、ディスク上のインデックス及びBDUにおける変更についてロックステップで更新されなくてはならない。各々のインデックス更新は、BDUオブジェクトを更新するジョブを実行したことの結果であることから、ジョブには、ディスク上のインデックス及びBDUオブジェクトと探索構造の一貫性を維持する付加的な責任が与えられる。JEPが故障している場合、回復時点でJEPは、BDUを走査することによってメモリ内の探索構造を再構築する。
BDUにおける変更はトランザクションがコミットされるまで反映されないことから、BDUオブジェクトに対する修正が、修正要求の送信直後に起こらない可能性がある。しかしながら、メモリ探索構造に対する修正は直ちに起こる。ユーザーが、BDUにコミットされなかったオブジェクトについての情報に対する問合せを提出した場合、そのオブジェクトの位置は特定され得ない。このようなコミットされていないオブジェクトについては、オブジェクト識別子(OID)が割当てされなかった可能性がある。このような場合には、ユーザーは単に、問合せの結果を廃棄することができる。データベース内の更新が探索構造内の更新より後ろに遅れる可能性があるという状況は時として、標準的データベースシステム内で発生し得る。オブジェクトが標準的データベースシステムにまだ書込まれていなかったならば、そのオブジェクトを発見することはできない。この状況に対処する代替的スキームは、1つのジョブを実行しているときに直ちに探索構造を変更せず、むしろ変更を蓄積してそれらを1つのトランザクションがコミットされた直後に適用することである。
図6は、システムアドミニストレータが1つのオブジェクトクラスのためのインデックスを定義できるようにするクラスエディタ50と呼ばれるユーザーインタフェースである。一般に、1つのオブジェクトは、人物タイプ又は製品タイプといったオブジェクトタイプによってカテゴリに分類できる。1つのオブジェクトタイプは多数のクラスを含むことができる;すなわち例えば、車両保険会社は、その被保険者を、総合保険担保範囲をもつ人々及び責任保険担保範囲をもつ人々に分類することができる。各々のクラスは、少なくとも1つの対応するインデックスを有している。各インデックスは、クラスエディタから編集できるキー属性及び非キー属性を有している。
クラスエディタ50は、システムアドミニストレータが自ら新規作成又は編集するインデックスについてのキー51を選択し、インデックスエントリ内に記憶することを望む非キー属性52を選択することを可能にする。図7においては、編集されつつあるインデックスは、Test::Personのクラス53を含んでいる。インデックスのキーはSSNであり、インデックスの各々のインデックスエントリはSSNについての情報、人物の住所、人物の住所に対応する郵便番号(図示せず)を内含している。
1人の人物が1つ以上の住所を有する可能性があることから、この人物を複数の郵便番号に結びつけることができる。同じ郵便番号をもつ全ての人物の位置を特定する上での効率を考えると、この郵便番号がインデックス内のキーである場合、多数の住所をもつ人物については、住所1つに1つずつの多数のインデックスエントリが新規作成される。
どんなインデックスが定義されているかを見い出すためには、システムアドミニストレータは、インデックスの定義を含むスキーマを編集し表示するべくオブジェクトスキーマウインドウを開くことができる。図7は、オブジェクトクラス(61、62及び63)及びそれらの付随するインデックス及び属性の定義を表示するオブジェクトスキーマウインドウ60を示している。このスキーマは、データベース内のオブジェクトのためのクラスのレイアウトを含有している。各クラスのレイアウトは、属性及び関係に関してそのクラスのインスタンスの物理的構造を記述している。さらにこのスキーマは、データベース及びプロセッサ間でオブジェクトをコンテンションなくいかに分散させるか、データベース内にロードすべき入力ファイルをいかにして構文解析するか、そして、多数のソースからのデータをいかに統合するかを記述している。
1つのオブジェクトの付加、削除又は更新が関与するタスクについての要求がUSPに到着する毎に常に、その要求について作用する1つ以上のジョブを新規作成するべくJCP350に対して要求が送られる。JCPは、そのオブジェクトクラスについてどのインデックスが定義されるかそしてそのインデックスのためのキーはどれかを見い出すためにスキーマ内の情報を使用する。その後、JCP350は、インデックスエントリの付加、削除及び更新といったようなインデックスに対する必要な変更を見極め、インデックスを更新しタスクを完成させるために新規作成される必要のあるジョブのシーケンスを決定する。要求された各々の動作は、オブジェクト及びそのそれぞれのインデックスエントリが修正される順序について異なる必要条件を有する。この必要条件は、インデックスの無欠性を維持するため、厳守されなくてはならない。
図8は、ファイル70をロードするためのインデックス修正プロセスの一例を示している。ファイル70は、BDU22内のオブジェクトの付加610、削除630及び更新650を必要とする可能性がある。例えば、ファイル70は、保険会社が取得したばかりの新しい部門の顧客記録を含んでいるかもしれない。取得した顧客記録は、既存の顧客についての複写された情報又はより最新の情報を含んでいてもよいし、あるいは又新しい顧客についての情報を含んでいてもよい。既存の顧客記録と取得した顧客記録を統合するためには、顧客記録を表わすBDUオブジェクトを付加、削除及び更新するべくジョブが新規作成される。新規作成されるジョブ及びそれらが行なわれなくてはならない順序の一例として、1つのオブジェクトを削除するとき(630)、オブジェクトとそのインデックスエントリの間のリンクをまず最初に削除しなければならない(631)。このとき、オブジェクトを参照する全てのインデックスエントリを削除するためにジョブが生成される(632、633)。インデックスエントリが削除された後、オブジェクトを削除するためにもう1つのジョブが産生される(634、635)。インデックスエントリはオブジェクトが削除される前に削除されなくてはならない:そうでなければ、もう1つのプロセスではオブジェクトが削除されてしまっている一方でオブジェクトにアクセスするべくインデックスエントリの1つを使用することが可能である。
Objectivity/DB(登録商標)といったようないくつかの実施においては、オブジェクトに対するポインタが再度使用される。オブジェクトに対するポインタは、オブジェクト識別子(OID)と呼ばれ、オブジェクトのデータベース、コンテナ、ページ番号及び記憶装置内のページスロットを特定する4つの16ビットの正負符号のついていない整数を内含する。削除されたオブジェクトのインデックスエントリは、削除されたオブジェクトのOIDを内含するが、このOIDは、削除されたオブジェクトと同じデータベース、コンテナ及び記録場所に付加されるもう1つのオブジェクトに再度割当てられた可能性がある。従って、1つのオブジェクトがそのインデックスエントリの前に削除された場合、2つの誤り条件のうちの一方、すなわち、プロセスが既存でないオブジェクトをアクセスしようと試みるか又はプロセスが誤ったオブジェクトを参照するといういずれかの条件が発生しうる。
オブジェクト及びそのインデックスエントリを削除する上でのコンテンションを避けるため、オブジェクトの削除を実施するジョブがUSPによりスケジュールされる。これらのジョブは、いくつかのコンテンションスペース全体にわたり分散させられていてよい。各々のジョブでは、その完了を表示するもう1つの「応答」ジョブが産生させられる。応答ジョブは同期化され、オブジェクトが存在するコンテンションスペース内にロードされる。全ての応答ジョブが実行セル内に到着した時(定足数の完了によって見極められるように)、全ての応答ジョブは、そのオブジェクトを削除する単一のジョブへと折畳みされる。
1つのオブジェクトを付加するためのステップの順序決定は、削除の逆である。1つのオブジェクトを付加する場合(610)、そのオブジェクトは、いずれかのインデックスエントリがそれを参照できるようになる前に新規作成されなくてはならない。1つのオブジェクトが新規作成され(611、612)、持続メモリ内に記憶される場合、各々1つのインデックスエントリを新規作成し(614、615)、各々が1つの該当するコンテンションスペース内で実行される「インサート」ジョブが産生される(613)。ここでこれらのジョブがオブジェクト新規作成と同じトランザクション内で新規作成されるという点に留意されたい。そうでなければ、このオブジェクトは、故障が発生した場合に、対応するジョブがないまま記憶された状態で終了してしまう可能性がある。次にオブジェクトとそのインデックスエントリの間でリンクを確立するためにジョブが新規作成される(617)。
1つのオブジェクトを更新するとき、更新はそのオブジェクトのインデックスエントリのいずれかに対しいかなる効果ももたない可能性がある。例えば、1人の人物の色の好みはその人物のオブジェクト内に記憶されているもののインデックスエントリのいずれの中にも記憶されない可能性がある。このような状況下では、インデックスエントリのためにいかなる更新も必要とされない。その他の例においては、更新には、インデックスエントリが更新されるか又は削除されることが必要となるかもしれないし、あるいは又新しいインデックスエントリを新規作成することが必要となるかもしれない。例えば、一人の人物の住所が変更され、住所がその人物のインデックスエントリ内に記憶された情報の一部である場合、インデックスエントリは更新されなくてはならない。その人物がもう1つの郵送部域内でもう1つの家を購入し、郵便番号によりインデックスが打鍵された(すなわちソートされた)場合、その人物の新しい家の住所を含む新しいインデックスエントリが挿入される必要がある。
1つのオブジェクトを更新するプロセスにおいて、JCP350は、そのインデックスエントリのいずれかを更新する前にオブジェクトを更新するべくジョブを新規作成する(650、651)。人物の住所を更新する例においては、インデックスエントリはそれが更新される前の旧住所を含んでいるものの、その人物のオブジェクトを指すインデックスエントリの中に含まれたOIDはなおも現行状態にある。従って、更新されたオブジェクトはなおも、旧インデックスエントリを用いることによってその位置を特定することができる。1つのオブジェクトを更新した時点で、JCP350は計算して、更新後に存在するはずのインデックスエントリのリストを作成する。次にこのリストは、どの再インデクシングジョブを実行する必要があるのか、すなわちどのインデックスエントリが更新され(652)、新規作成され(654)、削除され(653)又は未変更にとどまるべきかを見極めるため、オブジェクトに添付されたインデックスの現行リストと比較される。
インデックスエントリを削除すべきである(653)場合には、それをまずオブジェクトから接続解除し、その後JCP350がインデックスエントリを削除するべくジョブを新規作成する。このジョブは、完了を表わす応答ジョブをオブジェクトまで送り戻す。この応答ジョブは、以下で記述するウエイトフリーアルゴリズムのために必要である。インデックスエントリを付加すべきである場合、JCP350は、適切なコンテンションスペース内でインデックスエントリを新規作成するのに充分な情報を含むジョブを新規作成し、次に応答ジョブを、オブジェクトまで送り戻して新規作成されたインデックスエントリを表示する。インデックスエントリを更新するべきである場合、JCP350は、既存のインデックスエントリを更新するのに充分な情報を含むジョブを新規作成し、その後応答ジョブを完了を表示するオブジェクトへと送り戻す。インデックスエントリが未変更のままとどまるべきである場合、行なうべきことは何もない。
1つのオブジェクトに対して多数の重複する変更が起こるとき(すなわちインデックスエントリが全てオブジェクトと一致させられる前に発生する変更)、再インデクシングジョブが正しく作動するようにするためには、ウエイトフリーアルゴリズムが用いられる。以下で記述するように、ウエイトフリーアルゴリズムは、オブジェクトが未処理ジョブを有する間1つのオブジェクト内の変更を許容し、さらに全ての再インデクシングジョブの間のコンテンションを回避する。オブジェクトは、インデックスエントリ更新オペレーションのために2ビットのフィールドすなわち、再インデクシングインジケータ及びpleaseReindexインジケータを予約する。再インデクシングインジケータは、応答ジョブをまだ送り戻していない未処理再インデクシングジョブが存在することを表示する。pleaseReindexインジケータは、その再インデクシングジョブが完了する前にオブジェクトが変更されたことを表示する。個別の再インデクシングジョブからの応答は同期化される。この同期化により、全ての応答がそのオブジェクトの対応する実行セル内に存在するとき、全ての再インデクシング応答が単一のジョブの形に折畳みすることが可能となる。単一ジョブは、オブジェクトに添付されたインデックスエントリのリストを更新する。更新の直後に、オブジェクトの PleaseReindexインジケータは検査される。インジケータがセットされる場合は、それは、オブジェクトが終了したばかりの再インデクシングの間に変化したことを表示する。新しい変更によるもう1つの再インデクシングオペレーションが直ちに開始することになる。
1つのオブジェクトを削除するための要求は再インデクシングオペレーション中に到着する可能性がある。オブジェクト及びそのインデックスエントリに対するあらゆる更新はオブジェクトが削除された後消滅することから、削除要求は更新要求よりも優先される。オブジェクトの中では付加的な確保された2ビットフィールドが使用される。1つはdeleting であり、もう1つは pleaseDeleteである。Deletingビットは、そのオブジェクトが削除されつつあるか否かを表示し、pleaseDeleteは、オブジェクトを削除するための要求が存在するか否かを表示する。いずれかのビットがセットされた時点で、pleaseReindexインジケータは無視され、その後に続くオブジェクト更新要求も同様に無視される。
ユーザーは、BDUオブジェクトについてのある種の情報を読みとることのみを望む場合、問合せを送ることができる。問合せは、その他の大部分のジョブとは異なり、オブジェクト、インデックスエントリ又はインデックス内の変更を作り出さない。TCP/IPソケットを用いたUSPの実施態様においては、問合せは、ネットワークを介して伝送されるデータ量を減少させるべく問合せジョブとして取り扱うことができる。要求者がBDUオブジェクトの位置を特定するための問合せを提出すると、JCPはその問合せを問合せジョブの形へと変換し、これは次に、要求されたオブジェクトが存在するコンテンションスペースのJEPへと送られる。各々の問合せジョブがIDを有し、このIDは、結果を対応する問合せと整合させるべく発信元JCPのために使用される。問合せジョブには、ネットワーク上で送られるその他のジョブのように、シーケンス決定番号が与えられていない。問合せジョブがJEPへの途中でネットワーク伝送中に失なわれた場合、問合せを再提出するか否か(タイムアウトの後であることが考えられる)は、要求者次第である。失なわれた問合せの取扱いは、ウェブブラウザ(例えばマイクロソフト社のInternet Explorer)を用いて広域ウェブからある会社のデータベースにアクセスする顧客にとって合理的なものである。
問合せジョブを準備完了ジョブのキューに対し付加する代りに、JEPがそれを受信した時点で、異なるキューつまり問合せジョブのキューにこの問合せジョブを付加することができる。通常のジョブの間、さらには通常のジョブのステップ間でさえ、この問合せジョブのキューを検査することができる。待機中の問合せジョブが存在する場合、問合せは直ちに実行され、結果は、そのジョブのIDが添付された状態で発信元JCPへと送り戻される。問合せジョブはBDU内のデータしか読取らないことから、問合せがその他のジョブより先行できるようにすることにより何らかの順序づけ上の問題が導入されることはない。
BDU内の1つのオブジェクトは、インデックスを用いるだけでなく、オブジェクトをその他の関係するオブジェクトに連結させるリンクを用いてもその位置が特定され得る。数多くのBDUオブジェクトは互いに関係をもつ。例えば、ここで再び図1を参照すると、保険会社のデータ処理センタ191は、その被保険者のオブジェクトと製品のオブジェクトをBDU22内に記憶するととができる。被保険者であるビル(Bill)が地震保険をかけていると想定する。これは、ビルを表わすオブジェクトと地震保険を表わす製品オブジェクトの間に「所有権」関係が存在することを意味している。システムユーザーがビルの所有する製品オブジェクトの位置を特定したいと考えた場合、1つの方法はビルのオブジェクトを検索し、どの保険証券をビルが有しているかを探し、保険製品のオブジェクトのインデックス内で地震保険のインデックスエントリの位置を特定することにある。あるいは、ビルのオブジェクトと地震保険という製品のオブジェクトの間に直接的リンクを確立することによって検索可能である。直接リンクを用いると、目的とするオブジェクト(例えば保険製品オブジェクト)に関する情報を、インデックス内を進むことなく直接検索することができる。
オブジェクト間の直接リンクは、関係と呼ばれる。1つの関係は例えば、所有権又は親子関係であり得る。オブジェクト間の関係は、非同期関係マネージャ(ARM)と呼ばれる機構によって構築され得る。システムアドミニストレータは、オブジェクトの特定のクラス間の関係を定義する必要しかなく、ARM機構に従いクラス(すなわちオブジェクト)の対応するインスタンス間の関係を構築するために自動的にジョブが新規作成される。
ARMは、大規模分散型データベースシステム内といったような数100万の同時アクセスを可能にするシステムのためにはいかにして関係を構造化し維持すべきなのかを規定する。ARMは、分散型データベースを横断してオブジェクトが付加され、修正され削除されるにつれて、関係の無欠性を保証するように環境及び共通規則の組を提供する。
例えば、保険会社が、ビルの持つ地震保険の担保を停止する決定を下した場合、ARMは、地震保険の製品オブジェクトがデータベースから除去される前にビルと地震保険の間の関係が自動的に削除されることを保証する。関係の変更を実行するタスクは、高いスループット及び効率を可能にするべくUSPによってスケジュールされたジョブにより実施される。例えば、1つのオブジェクトが付加又は削除されるとき、付随する関係を付加又は削除するべく新しいジョブが産生される。同様にして、1つのオブジェクトを更新するのにその関係の更新が必要とされる場合、適切な関係を更新するためにジョブが産生される。
JEP300により実行されるジョブは、BDUオブジェクトを付加し、削除し又は更新するジョブであり得る。オブジェクト内の変更には、BDU内の関連するオブジェクトが付加、削除又は更新されることが必要となるかもしれない。付加、削除又は更新される必要のある関連するオブジェクトは、オブジェクト間の関係を追従することによって識別され位置特定され得る。関連するオブジェクトがひとたび発見されると、JEP300は、関連オブジェクトを更新するべく新しいジョブを産生する。
クラス間の新しい関係が、図7に示されているようなユーザーインタフェイスの中で定義され得る。このユーザーインタフェイスは、システムアドミニストレータが、例えば組織クラス61、人物クラス62及び製品クラス63といったようなオブジェクトクラス間の関係を付加及び削除することを可能にするスキーマウインドウ60を表示する。
新しい関係が定義された時点で、1つのクラスの中の各々のオブジェクトは、もう1つのクラスの中の対応するオブジェクトにリンクされなくてはならない。同様にして、JCP350によって新しいオブジェクトが作り出された時点で、新しいオブジェクトとその他の既存のオブジェクトの間の新しい関係が確立されなくてはならない。1つの関係にある既存のオブジェクトの位置を特定するためには、JCP350は、BDU22中の全てのオブジェクトのためのインデックスを使用する。スキーマ中に記憶された情報から、JCP350は、どのインデックスを選択すべきか及びいかにして情報がインデックス内でソートされるかを知っている。JCPは、各々の既存のオブジェクトと新しいオブジェクトの間の関係を確立するためもう1つのジョブを新規作成する。
多数のプロセッサ及びデータベースを横断して分散させることのできるオブジェクト間の関係を確立するためには、オブジェクトと同期オペレーションの間のメッセージ通過を管理するために付加的なジョブ及びオブジェクトを新規作成しなければならない。より特定的に言うと、各クラスに1つのロールオブジェクトといった1組の相互接続されたロールオブジェクトとして関係を実施することができる。図6及び図10(1)〜(4)は、既存のオブジェクト2及びオブジェクト3との新たに作成されたオブジェクト1の関係を確立するためのプロセスを例示している。オブジェクト1、オブジェクト2及びオブジェクト3は、それぞれクラス1、クラス2及びクラス3のインスタンスであり、オブジェクトは図9においてそれぞれC1、C2及びC3として示されている。
まず第1に、オブジェクトC1のためのジョブJ1によりロールオブジェクトR1が新規作成される(510及び620)。その後ジョブJ1at及びJ1btが新規作成され、各々ポインタがR1を指している状態で(520)、C2及びC3に対し送られる(622)。上添字「t」は、J1at及びJ1btが、同期ジョブを産生するためにタグと定数分数を支持していることを表わしている。J1at及びJ1btはロールR2及びR3を新規作成し(640及び660)、それぞれR2及びR3を結びつけるポインタをR1に送り戻す(531、532)。
J1at及びJ1btはさらに同期ジョブJ1a1s及びJ1b1sを産生し(530、642及び662)、それらをR1に送り戻す(643及び663)。上添字「s」は、J1a1s及びJ1b1sが同期ジョブであり、そのためJ1a1s及びJ1b1sのいずれもその両方の実行準備完了状態となるまで実行することができない、ということを示している。実行前に、J1a1s及びJ1b1sは、それぞれJ1a1s及びJ1b1sが支持するR2及びR3についての情報を含む単一のジョブの形に折畳みされる。情報は、R2及びR3を指すポインタ(531及び532)、及び以下で記述するC2及びC3の予め定められたキャッシュ情報を内含する。単一のジョブはポインタを記録し、R1内に予め定められたキャッシュ情報をキャッシュ記憶する(624)。
単一ジョブが完了した後、このジョブは最終新規作成ジョブJ2a及びJ2bを産生し、R1、R2及びR3の情報(540)と共にそれらをR2及びR3にそれぞれ送る(626)。R2及びR3は、その他2つのもののポインタ(541、542、543及び544)を記録するためにその情報を用い、それぞれその他2つのものについての情報をキャッシュ記憶する(644及び664)。そのロールがその他のロール全ての情報を有する(680)まで、関係を1つのオブジェクトが利用することはできない。
1つの関係が確立された後、システムユーザーは、関係に参加するその他のオブジェクトについてのある種の情報と共に、1つのオブジェクトの関係全てを表示させたいと考えるかもしれない。情報を表示する性能を増大させるため、オブジェクトのロールは、そのオブジェクトが関係をもつその他のオブジェクトについての情報をキャッシュ記憶する。例えば、一人の人物は、通常多数のデータベースを横断して分散されているその他の人々、製品及び組織に対する数多くの関係を有するかもしれない。多数のデータベースを横断して分散したオブジェクトについての情報を検索するのは、効率が良くない。従って、ロールオブジェクトは、その関係内のその他のオブジェクトからの情報をキャッシュ記憶する。
図11は、所有権関係に参加するロールオブジェクト内にキャッシュ記憶されるべきキャッシュ変数をユーザーが選択できるようにするユーザーインタフェース80を例示している。ユーザーは、最上部に「Data」としてラベルづけされた列81内の属性をマーキングすることによってキャッシュ変数を表示することができる。1つのオブジェクトの全ての関係の要約から、その関係内にあるその他のオブジェクトについてのキャッシュ記憶された情報を含め、リスト内に迅速に表示され得る。
全てのロールは、その付随するオブジェクトが修正された時点で増大するバージョン番号を有する。オブジェクトのバージョン番号が変更された時点で、その他のロール内にキャッシュ記憶されたオブジェクトの値を相応して更新できるようにそのオブジェクトの関係のその他のロールに対して1つのメッセージが送られる。バージョン番号は、65536バージョン毎に0に回帰する。
全てのロールは同様に、それが現在キャッシュ記憶したその他のロールすべてのバージョン及び各々の他のロールについて欠けているバージョンの数も追跡する。ネットワーク上での伝送中に可変的長さの時間だけバージョン番号を含むメッセージを遅延させ、このようにして、順序外受信をひき起こすことができることから、バージョンが欠如していることもある。各々のその他のロールについての欠如しているバージョン番号の数は、いくつの未処理メッセージがそのロールからなお受信される予定であるかを表示する。ロールは、未処理メッセージがまもなく到着する場合、自らを削除したいと考えないかもしれない。
欠如しているバージョンの数を計算するために、ロールは受信した新しいバージョン番号をとり、現行バージョン番号を減算する。差から1を引いたものが、欠如しているバージョンの数を表わす現合計に加算される。現行バージョンより少ないバージョンが受信された時点で、現行バージョンと受信バージョンの間の差が計算され、欠如バージョンの現合計が1だけ減分される。例えば、現行バージョンが6でありバージョン10が到着した場合、我々は10−6−1=3バージョンがなおも予想されているという事実を記録する(7、8、9)。バージョン10が到着した後、旧バージョン8を受信することはすなわち、なお2つの旧バージョンが通過状態で存在することを意味する(7及び9)。
付随するオブジェクトが削除されるか又は更新されたことの結果として、1つの関係を削除することが可能である。もはや必要でないことを理由として関係を削除することも同様に可能である。オブジェクトの間で1つの関係が削除される場合、関係削除のための1つのアルゴリズムが、その関係内の異なるオブジェクトから同時に削除要求が存在する場合でさえもその削除の適正さを保証する。このアルゴリズムは、たとえUSPがメッセージの到着順を保証しなくても物理的に削除されてしまったロールについてメッセージが到着することは決してないことを保証する。
削除プロセスは、1つのオブジェクトがそのロールの1つにそのロールの関係を削除するよう告げた時点で開始する。このロールはイニシエータと呼ばれる。スキーマ定義時点で、関係のロールクラスの1つは、コーディネータロールとして任意に選択される。コーディネータは、イニシエータとなることが許されている。
イニシエータが、削除のために既にマーキングされている場合、それは、削除がすでに進行中であり関係が場合によって削除されることになることを表わしている。こうして、イニシエータは何もしない。あるいは、イニシエータが削除のためマーキングされていない場合、それは削除のため自らマーキングし、メッセージ1をコーディネータロールに送る。イニシエータの最終バージョン番号は、メッセージ1内で中ほどへと入る。バージョン番号は、ロールキャッシュ更新要求を順序づけするために用いられる(すなわち1つのオブジェクトが変わるとき、そのオブジェクトのロールとの関係に参加する全てのロールは新しい情報でそのキャッシュを更新するよう要請される)。イニシエータロールは、削除のためにマーキングされているため、イニシエータロールのオブジェクトに対するその後の変更を無視し、その他のロールに変更メッセージを送らない。
コーディネータはメッセージ1を受理した時点で、計数器を増分させて、どれほどの隣接ロールが削除済みとしてマーキングされたかを表示する。これがこのようなメッセージの最初のものであった場合、メッセージ2が各ロールに対し送られる。
メッセージ2がロールにより受信された時点で、削除フラグが検査される。ロールが既に削除についてマーキングされている場合、それはすなわちメッセージ1が既にこのロールからコーディネータまで送られたことを意味する。従って、ロールは単に、メッセージ2が到着したことを記録し、いかなる応答も送らない。そうでなければ、ロールはそれ自体削除されたものとして自らにマーキングし、メッセージ1をコーディネータに送ってこのことを表示する。
メッセージ1及び2に対するこれらの規則は、コーディネータが各ロールから正確に1つのメッセージ1を受信し、ロールが削除済みとマーキングされた後に初めてこのメッセージを受信することになるよう保証している。このことは、たとえ、各々が関係の削除をトリガーしようとしている多数のイニシエータが存在する場合にさえ言えることである。
(コーディネータが各ロールからメッセージ1を受理したことから)全てのロールが削除済みとしてマーキングされたことをコーディネータ内の計数器が表示した時点で、コーディネータは、各ロールに対し、それを物理的に削除するのが安全であることを表示するメッセージ3を送る。
これらのメッセージ3は、コーディネータからロールに送られる最後のメッセージである。各々のロールはこれに先立ち既に削除済みとマーキングされているため、これらはまた互いにキャッシュ更新メッセージを送ることをやめている。しかしながら、ずいぶん前に送られしかもまだ到着していない(USPがメッセージの順序付けを保証しないことを理由として)メッセージも存在し得る。全てのメッセージが到着する前に、ロールを物理的に削除するのを避けるため、各ロールは、その他のロール各々に1つずつのバージョン番号のアレイを有する。バージョン番号は、対応するロールについての受信メッセージのうちの最後のバージョン番号を記録する。もう1つのアレイは、その他のロール各々について未処理メッセージの計数を維持し、この計数は、その他のロール各々からまだ到着していないメッセージがいくつあるかを表わしている。未処理メッセージは、標準的にキャッシュ更新メッセージである。
アルゴリズムは、1つのメッセージ3だけがロールに到着することを保証し、全てのロールについて最終バージョン番号のアレイを支持している。このメッセージが到着した時点で、物理的削除準備完了フラグがセットされる。ロール内部の計数器が、未処理入メッセージが全くないことを表示した場合、そのロールは直ちに削除される。そうでなければ、旧キャッシュ更新メッセージが最終的にロールに到着した時点で常に計数器は更新され、全てのメッセージが到着しロールが物理的削除準備完了としてマーキングされた場合、ロールはデータベースから物理的に削除される。
メッセージ2は、ロールがイニシエータである場合、メッセージ1の後にロールに到着する。各ロール内のフラグが、メッセージ2が既に到着したか否かを表示し、メッセージ2(ならびに上述のように何らかの未処理キャッシュ更新メッセージ)が到着するまで物理的削除は延期される。
以下に記すのは、3つのタイプのメッセージの中に含まれる情報の短い要約である:
メッセージ1(「ロールは削除のためマーキングされている」)には、次のものが含まれる:
− 削除のためにマーキングされたロール。
− そのロールの最終バージョン番号。
メッセージ2(「コーディネータに代って削除のためマーキングして下さい」)には以下のものが含まれる:
− コーディネータのロールの最終バージョン番号。
メッセージ3(「旧メッセージが全て説明された時点でロールを物理的に削除すること」)には、以下のものが含まれる:
− 各ロールの最終バージョン番号。
ロールが削除されたものとしてマーキングされた時点で、そのロールをそのオブジェクトから接続解除されなくてはならない。こうして、オブジェクトの観点からは、削除は既に起こっているように見える。
一例として、R2がコーディネータである3つの接続されたロールR1、R2及びR3を考慮する。図12及び図13(a)〜(f)を参照して、削除がR1で開始されていると想定する(810、820)。同様に、例全体について通過状態にあるR1からR3の未処理キャッシュ更新メッセージが存在することも仮定する。例は、各々のロールが取るステップを反映している。
R1: 私はマーキングされておらず(811)、従って、私は私自身を削除済みとしてマーキングし(813)、メッセージ1をコーディネータであるR2に送る(814)。私は、自分の最終バージョン番号FV1を内含することになる。
(R1からR2への通過中のいかなるキャッシュ更新メッセージも存在しないと想定する)。
R2: R1からメッセージ1を受取り(830)、私は私のロールバージョン番号テーブル内に、FV1がR1についての現行バージョンであることを記録する(835)。私には、R1からR2まで通過中のキャッシュ更新メッセージが全く存在しないことがわかる。ここで私は各ロール(R1、R2及びR3)に対しメッセージ2を送り出す(837)。このメッセージは私の最終バージョン番号FV2を内含している。
R1: 私はメッセージ2を受信する(831)が、すでに削除済みと自らマーキングしたため、私は単純にコーディネータ(R2)の最終バージョン番号を記録する。
R2: 私はメッセージ2を受信する(831)。私はまだ削除済みとして自らマーキングしていない(832)ことから、私は自ら削除済み(833)とマーキングし、私の最終バージョン番号FV2を含めたメッセージ1をコーディネータ(すなわち私自身)に送る(834)。
R3: 私はメッセージ2を受信する(831)。私はまだ削除済みと自らマーキングしていないことから(832)、私は削除済みと自らマーキングし(833)、私の最終バージョン番号FV3を含めコーディネータ(R2)にメッセージ1を送る(834)。
(R2が、R2からのメッセージ2を受信する前のR3からメッセージ1を受信すると想定する)。
R2: 私はまず最初にR3からメッセージ1を受信する。私は、私の現行バージョンアレイの中にR3の最終バージョン番号を記録する(835)。2つのメッセージ1(R1及びR3から)しか受信していないことから、他に何も行なわない。
R2: 私は次にR2からメッセージ1を受信する(831)。これは私の3番目のメッセージ1であったことから、今や、全てのロールの全ての最終バージョン番号ならびにそれら全てが削除のためにマーキングされているということがわかっている。従って私は、メッセージ3を各ロールに送り(838)、各メッセージ内の最終バージョン番号FV1、FV2及びFV3を渡す。
(R1、R2及びR3がR2からメッセージ3を受信した後、R1及びR2について未処理のメッセージは全く存在しないが、R3について1つの未処理メッセージが存在すると想定する)。
R1: 私はR2から、私が物理的に自ら削除できることを表示するメッセージ3を受信する。私は、自分の現行バージョンに対し最終バージョン番号を調和させる(839)。すなわち、私は、私の未処理メッセージ計数のアレイ内の未処理メッセージについてチェックする。何もないことがわかる。従って、私は自分自身を削除する(840)。
R2: 私はR2から、私が物理的に自ら削除できることを表示するメッセージ3を受信する。私は、自分の現行バージョンに対し最終バージョン番号を調和させる(839)。すなわち、私は、私の未処理メッセージ計数のアレイ内の未処理メッセージについてチェックする。何もないことがわかる。従って、私は自分自身を削除する(840)。
R3: 私はR2から、私が物理的に自ら削除できることを表示するメッセージ3を受信する。私は、自分の現行バージョンに対し最終バージョン番号を調和させる(839)。すなわち、私は、私の未処理メッセージ計数のアレイ内の未処理メッセージについてチェックする。R1からの1つの未処理キャッシュ更新メッセージが存在することがわかる。私は、物理的削除準備完了として私自身をマーキングし、次のメッセージを待機する(841)。
R3: 私は、R1から最終未処理キャッシュ更新メッセージを受信し(842)、それが到着したことを書き留め、それが私の待っている最後のメッセージであったこと及び私の物理的削除準備完了状態がセットされていること(839)を通知する。その後私は、データベースから自分自身を物理的に削除する(840)。
ここで再び図9を参照すると、1つの関係を削除するためのメッセージは、時としてロールが関係を新規作成中であるときに到着することがある。メッセージが、既存でないロールに送られるのを妨げるため、ロールは自らを削除する前に新規作成ジョブを完了することになる。ロールが、最終的新規作成ジョブ(J2a又はJ2b)を受信してしまう前に削除済みメッセージを受理した場合、それは自らを削除済みとしてマーキングし、最終的新規作成ジョブが受信されるまで待機する。最終新規作成ジョブが受信されると直ちに、ロールは削除メッセージの処理に着手することになる。
付属書類Aは、VisualWorks SmallTalk5i.lがObjectivity/DB5.2.2.データベースシステムと共に設置されているシステム上で使用するための本発明の実施のソースコードを内含する。
その他の実施態様も冒頭の請求項の範囲内に入る。例えば、本発明は、関係データベースといったような、オブジェクトデータベースではないデータベース上で実施することができる。オブジェクトデータベースにおいては、データオブジェクトはデータ項目として参照され得、データオブジェクト属性は、データ要素として参照され得る。関係データベースにおいては、データ記録はデータ項目とみなすことができ、データフィールドは、データ要素とみなすことができる。