説明

トランザクション処理システム、方法及びプログラム

【課題】シンプルな構成のKVS上で、ロールバックを不必要に発生させることなく、分散トランザクションを実現する。
【解決手段】キーをグローバル・トランザクションID、バリューを{トランザクションの状態,終了待ちグローバル・トランザクションID}とする、管理用マップ412a〜412dを用意する。グローバル・トランザクションの開始処理では、管理用マップのキーを管理するサーバ106a〜106d上で、管理用ローカル・トランザクションを開始する。グローバル・トランザクションの終了を待機する処理では、管理用マップのキーを管理するサーバ上で、ロック開放待ち用ローカル・トランザクションを開始し、競合するトランザクションの終了を待機する。

【発明の詳細な説明】
【技術分野】
【0001】
この発明は、分散処理システム、特に分散データベース・システム上でのトランザクションの処理に関し、より詳しくは、キー・バリュー・ストア(Key Value Store、以下KVSと称する)方式におけるトランザクションの処理に関するものである。
【背景技術】
【0002】
分散データベース・システムは周知であり、例えば、次のような従来技術がある。
特開2007−188518号公報は、オーナーシップグループを用いる分散データベース・システムに関し、データ項目のオーナーシップを示すデータを変更するステップを、不可分(atomic)の動作とすることを開示する。
【0003】
分散データベース・システムは一般に、リレーショナル・データベースを実装し、問い合わせにSQLのような構文を用いる。
【0004】
最近になって、キー(key)とバリュー(value)の組を書き込み、キーを指定することでバリューを読み出すことができる、キー・バリュー・ストア(KVS)と呼ばれるデータベース管理ソフトウェアが使われるようになってきた。KVSの特徴は、問い合わせがシンプルであるため検索が高速であり、使用するサーバの台数が増えるほど性能を高めることができるというケーラビリティに優れる。そこで、複数台のサーバにデータを分散させることができる分散KVSも実装されている。
【0005】
また、KVSでは、素朴な実装では、処理の原子性(atomicity)、分離性(isolation)は、細かい処理単位に限定されてしまう。例えば、memcachedや、Redis等のKVSでは、1つの照会・更新処理の原子性・分離性しか保障されない。また、WebSphere eXtreme Scaleや、Google App Engineでは、1台のサーバで管理するデータに対する照会・更新処理の原子性・分離性しか保障されない。しかし、アプリケーションが複数のサーバ上のデータに対する更新処理を行う場合、それらの処理に対して原子性・分離性が必須となる場合がある。
【0006】
一方、従来の分散データベースのように、分散ロック機構を利用した場合、システム全体が複雑となり、KVSの簡潔な実装による特性を生かすことができない。すなわち、KVSの各サーバでの複数の照会・更新処理に対するトランザクション原子性が保障される分散KVS上で、その各サーバの排他制御機構を用いて、システム全体のトランザクション原子性・分離性を保障するための、複数のサーバを跨った排他制御機構が必須である。
【0007】
すなわち、アプリケーション上のトランザクション(グローバル・トランザクション)の各処理を、KVS上の複数トランザクション(ローカル・トランザクション)として処理することで、分散トランザクションをKVS上で実現可能である。より具体的には次のようにする。
− まず、KVSのバリューを、ロックの状態(ロックを保持するグローバル・トランザクションIDとロックの種類)とコミット済みのバリュー、更新中のバリューとする。
− また、管理用マップをKVS上に別途用意し、グローバル・トランザクションの開始時は、管理用マップにグローバル・トランザクションの状態を追加する、ローカル・トランザクションを処理する。
− 照会・更新処理は、ロックの状態、コミット済みのバリュー、更新中のバリューを照会・更新するローカル・トランザクションとして処理する。
− コミット・ロールバック処理は、複数のローカル・トランザクションとして実現する。そして、照会・更新した全てのキーごとに、ロックの状態、コミット済みのバリュー、更新中のバリューを更新するローカル・トランザクションとする。
【0008】
このような手法の例として、「オープンソース徹底活用 Slim3 on Google App Engine for Java」ひがやすお・小川信一著、秀和システム、p.241-251に記述された手法がある。そこには、Google App Engineでグローバル・トランザクションを実現する方法が開示されている。
【0009】
また、http://research.google.com/pubs/pub36726.htmlには、Google Percolatorが記述されている。
【0010】
従来技法は、アプリケーションが異常終了する場合を想定し、管理用マップをKVSに用意し、トランザクションの状態(Working, Committed、Aborted)を管理する。そのとき、照会時、ロックを保持していると思われるトランザクションの状態が、Committed、Abortedの場合は、それぞれ、コミット済みのバリュー、更新前のバリューを利用可能となる。しかし、このようなシステムにおいては、ロックが競合した際には、分離性を保障するには、いかなる場合も、ロールバックする必要がある。
【0011】
http://labs.google.com/papers/chubby.htmlに記述されている、Google Chubbyは、分散ロック機構を利用することにより、分散トランザクションを実現可能とする。しかし、別途分散ロック機構を構築することは、ソフトウェア開発コスト及び管理コストが余分にかかる。
【先行技術文献】
【特許文献】
【0012】
【特許文献1】特開2007−188518号公報
【非特許文献】
【0013】
【非特許文献1】「オープンソース徹底活用 Slim3 on Google App Engine for Java」ひがやすお・小川信一著、秀和システム、p.241-251
【非特許文献2】http://research.google.com/pubs/pub36726.html
【非特許文献3】http://labs.google.com/papers/chubby.html
【発明の概要】
【発明が解決しようとする課題】
【0014】
この発明の目的は、シンプルな構成のKVS上で、ロールバックを不必要に発生させることなく、分散トランザクションを実現することにある。
【課題を解決するための手段】
【0015】
本発明は、各サーバの排他制御機構を用いて、各サーバでのローカル・トランザクションの原子性・分離性が保障される分散KVS上で、トランザクション間のロックの依存関係を保持し、ロックの開放待ちをKVSの排他制御機構を用いて認識することによって、上記課題を解決する。
【0016】
より具体的には、本発明のシステムは、キーをグローバル・トランザクションID、バリューを{グローバル・トランザクションの状態、終了待ちグローバル・トランザクションIDリスト}とする、管理用マップを用意する。
【0017】
そして、[TxID]をグローバル・トランザクションIDとするグローバル・トランザクションの開始処理では、本発明のシステムは、KVS上で、管理用マップのキー [TxID]を管理するサーバ上で、管理用ローカル・トランザクションを開始する。次に、管理用ローカル・トランザクションで、[TxID]をキー、{working, null}をバリューとするキー・バリュー・ペア(Key-Value Pair)を挿入する。この管理用ローカル・トランザクションは、グローバル・トランザクションが終了(コミットもしくはロールバック)する際、もしくは、グローバル・トランザクションが他のグローバル・トランザクションのロック開放待ちとなるまで、終了しない。
【0018】
[TxID]をグローバル・トランザクションIDとするグローバル・トランザクションが、[終了待ちTxID]のグローバル・トランザクションの終了を待機する処理では、本発明のシステムは、管理用ローカル・トランザクションで、 [TxID]をキーとするバリューを、{waiting, [終了待ちTxID]}に更新し、管理用ローカル・トランザクションをコミットする。次に、管理用マップのキー [終了待ちTxID] を管理するサーバ上で、ロック開放待ち用ローカル・トランザクションを開始し、キー[終了待ちTxID]のバリューを照会する。
【0019】
このとき、照会したバリューが存在しない、もしくは、バリューにおけるグローバル・トランザクションの状態がcommitted、abortedの場合、本発明のシステムは、ロック開放待ち用ローカル・トランザクションをコミットし、再度管理用ローカル・トランザクションを開始、 [TxID]をキーとするバリューを、{working,null}に更新し、ロックの競合が終了したことを通知する(再度、競合している可能性はある)。
【0020】
一方、照会したバリューにおける、 [終了待ちTxID]の状態がwaitingで、バリューとして、さらに終了待ちTxIDリストが存在する場合、本発明のシステムは、ロック開放待ち用ローカル・トランザクションをコミットし、[TxID]の終了待ちTxIDリストにこの終了待ちTxIDリストを追加して新たな[TxID]の終了待ちTxIDリストを生成する。そして、再度[TxID]をキーとして管理するサーバ上で管理用ローカル・トランザクションを開始して、[TxID]のグローバル・トランザクションの状態をwaitingに、また、[TxID]の終了待ちTxIDリストを新たに生成したリストに更新し、コミットする。 コミット後、新たに生成した[TxID]の終了待ちTxIDリストの末尾のTxIDのグローバル・トランザクションに対する終了待機処理を行う。なお、[TxID]が、新たに生成した[TxID]の終了待ちTxIDリスト内に含まれる場合は、ロールバックの処理を行い、アプリケーションにロールバックを通知する。これは、デッドロックの可能性がある。
【0021】
トランザクションをコミットまたはロールバックする場合、本発明のシステムは、管理用ローカル・トランザクションにおいて、 [TxID]をキーとするバリューを、{committed,null}、もしくは、 {aborted,null}に更新し、管理用ローカル・トランザクションをコミットする。
【発明の効果】
【0022】
この発明によれば、シンプルなKVSにおいても。キー・バリュー・ペアのパーティショニングを考慮する必要がなく、利用用途が広がる。従来は、シンプルなKVSは、銀行口座の振替用アプリケーションは、ユーザーIDごとにデータを複数サーバに分割する場合、使えなかった。
【0023】
また、この発明によれば、KVS上で、分散ロック機構を別途実装する必要なく、分散トランザクションを実現することができる。
【0024】
さらに、この発明に従う、管理用マップに対するトランザクション処理、アプリケーション用マップに対するトランザクション処理は、サーバ増加分だけスループットを増加させることができる。また、ロックの競合発生時にも、ロックを待機させるため、オーバヘッドは少ない。
【0025】
結局、この発明によれば、管理マップの排他ロックをトランザクション中維持し続けることにより、不用意なロールバックを減らすことができるという効果が得られる。
【図面の簡単な説明】
【0026】
【図1】本発明の実施するためのシステム全体の概要図である。
【図2】クライアント・コンピュータのハードウェアの概要ブロック図である。
【図3】サーバのハードウェアの概要ブロック図である。
【図4】クライアント・コンピュータとサーバにおける機能ブロック図である。
【図5】従来のKVSシステムの概要を示す図である。
【図6】従来のKVSシステムの概要を示す図である。
【図7】従来のKVSシステムの概要を示す図である。
【図8】本発明の従来のKVSシステムの概要を示す図である。
【図9】トランザクションの開始時の処理のフローチャートを示す図である。
【図10】照会時の処理のフローチャートを示す図である。
【図11】更新時の処理のフローチャートを示す図である。
【図12】コミット時の処理のフローチャートを示す図である。
【図13】あるトランザクションが、別トランザクションの終了を待機する処理のフローチャートを示す図である。
【図14】ロールバック時の処理のフローチャートを示す図である。
【図15】トランザクションの処理の一例を示す図である。
【図16】トランザクションの処理の一例を示す図である。
【図17】トランザクションの処理の一例を示す図である。
【図18】トランザクションの処理の一例を示す図である。
【発明を実施するための形態】
【0027】
以下、図面を参照して、本発明の実施例を説明する。特に断わらない限り、同一の参照番号は、図面を通して、同一の対象を指すものとする。また、以下で説明するのは、本発明の一実施形態であり、この発明を、この実施例で説明する内容に限定する意図はないことに留意されたい。
【0028】
図1は、本発明の実施するためのシステムの全体を示す概要図である。図1において、複数のクライアント・コンピュータ102a、102b・・・102zは、インターネット104を介して、HTTPなどのプロトコルにより、分散処理システム106にアクセスする。
【0029】
分散処理システム106は、LANまたはWANなどの仕組みにより相互接続された複数のサーバ106a、106b、・・・、106zをもつ。分散サーバ・システム106は、キー・バリュー・ストア(KVS)の仕組みで、分散データベースを構築するシステムである。すなわち、各サーバ106a、106b、・・・、106zにはIDが付与され、この方式には限定されないが、好適には、キーのハッシュ・バリューのmodを計算することで、そのキーを保持するサーバが一意的に決まる。
【0030】
従って、クライアント・コンピュータ102a、102b・・・102zは、照会するキーで、アクセスするサーバ106a、106b、・・・、106zが決定される。好適には、サーバ106a、106b、・・・、106zのうちの一台がカタログ・サーバと呼ばれるサーバで、そこには、他のサーバに格納されているキーその他の情報が格納され、クライアント・コンピュータ102a、102b・・・102zは、カタログ・サーバに一旦アクセスして、サーバ106a、106b、・・・、106zのうちのどのサーバにアクセスするかの情報を取得してから、指示されたサーバとの接続を確立する。あるいは、クライアント・コンピュータがアクセスした任意のサーバが他の複数のサーバにブロードキャストして、情報を取得する方式も使用できる。以下での説明では便宜上、クライアント・コンピュータが、目的とするサーバを見つけて接続を確立したところから説明する。
【0031】
クライアント・コンピュータ102a、102b・・・102zは、分散処理システム106にアクセスするために、一意的なグローバル・トランザクションIDを生成して、その後の分散処理システム106とのトランザクションに、そのグローバル・トランザクションIDを使用する。
【0032】
次に、図2を参照して、図1で参照番号102a、102b・・・102zのように示されているクライアント・コンピュータのハードウェア構成について、説明する。図2において、クライアント・コンピュータは、主記憶206、CPU204、IDEコントローラ208をもち、これらは、バス202に接続されている。バス202には更に、ディスプレイ・コントローラ214と、通信インターフェース218と、USBインターフェース220と、オーディオ・インターフェース222と、キーボード・マウス・コントローラ228が接続されている。IDEコントローラ208には、ハードディスク・ドライブ(HDD)210と、DVDドライブ212が接続されている。DVDドライブ212は、必要に応じて、CD−ROMやDVDから、プログラムを導入するために使用する。ディスプレイ・コントローラ214には、好適には、LCD画面をもつディスプレイ装置216が接続されている。ディスプレイ装置216には、Webブラウザを通じて、アプリケーションの画面が表示される。
【0033】
USBインターフェース220には、必要に応じて、拡張ハードディスクなどのデバイスを接続をすることができる。
【0034】
キーボード・マウス・コントローラ228には、キーボード230と、マウス232が接続されている。キーボード230は、検索のためのキーデータや、パスワードなどを打ち込むために使用される。
【0035】
CPU204は、例えば、32ビット・アーキテクチャまたは64ビット・アーキテクチャに基づく任意のものでよく、インテル社のPentium(インテル・コーポレーションの商標)4、Core(商標)2 Duo、AMD社のAthlon(商標)などを使用することができる。
【0036】
ハードディスク・ドライブ210には、少なくとも、オペレーティング・システムと、、分散処理システム106にアクセスするためのクライアント側のアプリケーション・プログラム402a(図4)が格納されており、システムの起動時に、オペレーティング・システムは、メインメモリ206にロードされる。オペレーティング・システムは、Windows XP(マイクロソフト・コーポレーションの商標)、Windows Vista(マイクロソフト・コーポレーションの商標)、Windows(マイクロソフト・コーポレーションの商標) 7、Linux(Linus Torvaldsの商標)などを使用することができる。クライアント側のアプリケーション・プログラム402aは、図4のブロック図や、図9〜図14のフローチャートを参照して、後で詳細に説明する。
【0037】
通信インターフェース218は、オペレーティング・システムが提供するTCP/IP通信機能を利用して、イーサネット(商標)・プロトコルなどにより、インターネット104を介して、分散処理システム106と通信する。
【0038】
図3は、分散処理システム106における、サーバ106aなどのハードウェア構成の概要ブロック図である。図示されているように、インターネット104を介して、サーバ106a、106a、・・・106zが接続されている。サーバ106a、106a、・・・106zは基本的に同一の構成なので、ここでは代表的にサーバ106aを示す。図3に示すように、クライアント・コンピュータ102a、102b・・・102zは、インターネット104を経由して、サーバ106aの通信インターフェース302に接続される。通信インターフェース302はさらに、バス304に接続され、バス304には、CPU306、主記憶(RAM)308、及びハードディスク・ドライブ(HDD)310が接続されている。
【0039】
図示しないが、サーバ106aにはさらに、キーボード、マウス、及びディスプレイが接続され、これらによって、保守担当者が、サーバ106全体の管理やメンテナンス作業を行うようにしてもよい。
【0040】
サーバ106aのハードディスク・ドライブ310には、オペレーティング・システムが保存されている。
【0041】
ハードディスク・ドライブ310にはさらに、サーバ106aをWebサーバとして機能させるためのApacheなどのソフトウェア、及びJava仮想環境を実現するJava EE、及びJava仮想環境上で動作する本発明に係る後述するアプリケーション・プログラム402aが保存され、サーバ106aの立ち上げ時に、主記憶308にロードされて、動作する。これによって、クライアント・コンピュータ102a、102b・・・102zが、TCP/IPのプロトコルで、サーバ106にアクセスすることが可能となる。
【0042】
サーバ106aのハードディスク・ドライブ310にはさらに、IBM(R) WebSphere eXtreme ScaleなどのKVSを実現するためのソフトウェアが保存されている。ハードディスク・ドライブ310にはまた、本発明に従う、KVS用のトランザクション処理プログラム406a(図4)が保存されている。このトランザクション処理プログラム406aの機能については、図4のブロック図や、図9〜図14のフローチャートを参照して、後で詳細に説明する。
【0043】
尚、上記サーバ106aとして、インターナョナル・ビジネス・マシーンズ・コーポレーションから購入可能な、IBM(インターナョナル・ビジネス・マシーンズ・コーポレーションの商標)System X、System i、System pなどの機種のサーバを使うことができる。その際、使用可能なオペレーティング・システムは、AIX(インターナョナル・ビジネス・マシーンズ・コーポレーションの商標)、UNIX(The Open Groupの商標)、Linux(商標)、Windows(商標)2003 Serverなどがある。
【0044】
図4は、クライアント・コンピュータ102a、102b・・・102zと、サーバ106a、106b、・・・106zの各々における、処理プログラムの概要ブロック図を示す。なおここでは代表的に、クライアント・コンピュータ102aとサーバ106aを示す。
【0045】
クライアント・コンピュータ側のアプリケーション・プログラム402aは、ハードティスク・ドライブ210に保存されており、クライアント・コンピュータのユーザーの所定の操作で主記憶202にロードされて実行され、クライアント・コンピュータから、サーバ上にあるKVSシステムに対して、トランザクションの開始、データの照会、データの更新、コミットなどの処理を指示する機能をもつ。
【0046】
アプリケーション・プログラム402aは、システム全体で一意的なグローバル・トランザクションID(TxID)を生成する機能404aをもつ。グローバル・トランザクションIDの生成方法の1つの例は、クライアント・コンピュータ102a、102b・・・102zと、サーバ106a、106b、・・・106zの各々に固有のIDを付与しておき、各クライアント・コンピュータでトランザクションを開始する度に、そのクライアント・コンピュータのID+クライアント・コンピュータ内の増分される通し番号をグローバル・トランザクションIDとすることであるが、システム全体で一意的なグローバル・トランザクションIDになるようにする任意の方法を使用してもよい。
【0047】
アプリケーション・プログラム402aは、グローバル・トランザクションIDを生成してサーバ106aにアクセスすることができるが、別グローバル・トランザクションIDを生成することにより、同時に複数のサーバにアクセスすることができる。
【0048】
サーバ106aのハードティスク・ドライブ310には、トランザクション処理プログラム406aと、例えばIBM(R) WebSphere eXtreme ScaleであるKVSプログラム408aと、KVSプログラム408aによって参照される、キー(KEY)とバリュー(VALUE)のペアが保存され、トランザクション処理プログラム406aとKVSプログラム408aは、サーバ106aのスタートアップ時に、主記憶308にロードされて動作する。
【0049】
トランザクション処理プログラム406aは、クライアント・コンピュータ102aからの、グローバル・トランザクションIDを伴うリクエストに応答して、レコードのロック、ロールバックなどの動作を行うようにKVSプログラム408aを制御するとともに、好適には主記憶308に、グローバル・トランザクションIDと、状態と、待ちグローバル・トランザクションIDを含むエントリをもつ管理用マップ412aを作成して、サーバ毎に維持する。
【0050】
さて、本発明に従うKVSシステムの構成と動作を説明する前に、従来の典型的ないくつかのKVSシステムの構成と動作を説明する。これらを参照することにより、本発明に従うシステムの特徴がより明らかになるものと思量する。
【0051】
図5は、従来の典型的なKVSの構成を示す図である。ここで改めてKVSについて説明すると、図示されているように、データはデータ502a、502b、502c、502dのように分割され、複数のサーバ102a、102b、102c、102dに分散して配置される。クライアント・コンピュータ102aは、1台のサーバに対して、トランザクション処理を要求する。このとき。互いに素(disjoint)になるように、データは分散配置されている。データを配置するサーバは、好適には、キーのハッシュ・バリューのmodを計算することで決定される。
【0052】
クライアント・コンピュータ102aは、begin(トランザクションを開始する)、put(バリューを対応付ける)、get(対応するバリューを取得する)、commit(コミット、すなわち更新を確定する)などのコマンドを、キーのバリューによって決まるサーバに送って処理を要求する。
【0053】
このような従来構成のKVSは、分散トランザクションをサポートしていないので、各トランザクションでの更新範囲が複雑な場合、利用できない。トランザクションでの更新範囲が複雑になる例として、銀行口座の振込み、特に各口座残高を分散配置した場合や、ショッピングサイトにおいて、アカウント毎の履歴と、商品の在庫数を分散配置した場合がある。
【0054】
そこで、図6のようなKVSの構成が実現された。この構成においては、データを格納するフィールドを拡張して、dirty updateを格納するフィールドNEXTと、ロックバージョンを格納するVERのフィールドを、参照番号602a、602b、602c、602dに示すように追加した。
【0055】
これによれば、クライアント102aは、データにアクセスする前にロックを獲得する。そして、更新時、dirty updateとロックのバージョンを書き込む。一方、分散ロック機構604が別途設けられて、コミットされたロックのバージョンを管理する。その際、ロック獲得が成功したにも拘らず、NEXTバリューが存在する場合は、NEXTバリューをNOWバリューに変更し、ロック・バージョンを更新して、処理を続行する。このような仕組みにより、分散トランザクションは実現可能である。しかし、別途分散ロック機構604を構築することは、ソフトウェアの開発コスト、管理コストの上昇につながる。
【0056】
そこで、別途の分散ロック機構を用いない、図7に示すようなKVSの構成が提案された。この構成では、データのテーブル702a、702b、702c、702d以外に、各サーバ106a、106b、106c、106dに、グローバル・トランザクションID(TxID)及びトランザクションの状態とからなる、トランザクションの状態を記録する管理テーブル704a、704b、704c、704dをそれぞれ別途設ける。この構成では、クライアント102aは、照会したバージョンを記録し、照会したバージョンが更新されていない場合のみコミット可能とする。そして、コミット後、別トランザクションで、トランザクション状態を更新し、バリューを更新する。
【0057】
この構成では、競合時、すなわち複数のクライアントが同一のデータを更新する場合、既存のトランザクションの状態をローバック状態にする。これによって、分散トランザクションは実現可能であるが、楽観的トランザクションしか実現できない。また、既存の製品のみで実現可能であるが、競合が発生した場合、ロールバックが多発し、性能が向上しない可能性がある。
【0058】
図8は、図7に示すようなKVSの構成を改善した、本発明の構成を示す。ここでの参照番号は、図4の機能ブロック図に対応する。すなわち、各サーバ106a、106b、106c、106dに、グローバル・トランザクションID(TxID)及びトランザクションの状態と、終了待ちグローバル・トランザクションIDとからなる、管理用マップ412a、412b、412c、412dをそれぞれ別途設ける。そこで、STATEのフィールドに格納されるのがトランザクションの状態であり、WAITのフィールドに格納されるのが終了待ちグローバル・トランザクションIDである。
【0059】
また、各サーバ106a、106b、106c、106dには、KVSのデータを格納するテーブル(データ・マップ)410a、410b、410c、410dも設けられる。データ・マップ410a、410b、410c、410dはそれぞれ、キーを入れるフィールドであるKEYと、コミット確定済みのバリューを入れるフィールドであるNOWと、更新中のバリューを格納するフィールドNEXTと、ロック状態、すなわち更新中のグローバル・トランザクションID TxIDを格納するフィールドWRITINGと、照会中のグローバル・トランザクションIDTxIDsを格納するREADINGをもつ。
【0060】
この構成では、クライアント102aは、ロックの情報を照会・更新毎に更新する。そして、ロックが競合時、トランザクションの状態を更新し、終了待ちトランザクションの状態を監視する。コミットの後、クライアント102aは、トランザクション状態を更新し、別トランザクションでバリューを更新する。
【0061】
複数のクライアントが、同一のデータを更新する場合、すなわち競合時、競合するトランザクションの終了を既存のロック機構を利用することで、待機する。
【0062】
次に、本発明の処理のデータ構造とインターフェースについて説明する。
想定するKVSのマップ・インタフェースは、次のとおりである。
get(key) :keyに対する共有ロックを獲得し、対応するvalueを取得する。
put(key,value) :keyに対する排他ロックを獲得し、valueを対応付ける。
cas(key,prev, value) :keyに対する排他ロックを獲得し、バリューがprevだった場合に、valueを対応付ける。
remove(key) :keyに対する排他ロックを獲得し、valueを削除する。
commit() :keyに対する更新を確定し、獲得した全てのロックを開放する。
【0063】
マップ構成(1つの分散マップをアプリケーションが利用することを想定)
トランザクションの状態管理用のマップ(TxStateMap)。これは、図8に示すテーブル412a、412b、412cなどである。
key : TxID (グローバル・トランザクションID)
value: 状態 (Working|Committed|Rollbacked|Waiting) (STATE)、待機中TxID(WAITING)。
データ管理とロックの状態管理用のマップ (DataMap)。これは、図8に示すデータ・マップ410a、410b、410cなどである。
key: アプリケーションが指定するkey
value: コミット確定済みのバリュー(NOW)、更新中のバリュー(NEXT)、ロック状態、すなわち更新中のグローバル・トランザクションID (WRITING)、照会中のグローバル・トランザクションIDのリスト(READING)。
【0064】
また、トランザクションを実行中のクライアントがもつ状態として、以下のものがある。
TxID
− グローバル・トランザクションID
− これは、トランザクション開始時に生成される。
DirtyList
− 更新中のDataMapのバリュー
ReadingKeyList
− 照会中のDataMapのkey
さらにこの実施例では、終了済みTxIDリストとして、FinishTxIDsも用意される。
【0065】
次に、図9〜図14のフローチャートを参照して、本発明の処理について説明する。図9〜図14のフローチャートの動作を通して、基本的には、クライアント・コンピュータから指示が出され、その指示に応答して、サーバで処理が行われ、必要に応じてサーバからクライアントに応答が返される態様である。
【0066】
まず図9は、トランザクションの開始時の処理のフローチャートを示す。この処理は基本的に、クライアント・コンピュータ102a、102b、・・・102zのアプリケーション・プログラム402a、402b、・・・402zのどれかで実行される。
【0067】
ステップ902では、クライアント・コンピュータは、クライアント・コンピュータ固有のID+クライアント・コンピュータ内の増分される通し番号等により、グローバル・トランザクションID TxIDを生成する。
【0068】
ステップ904では、クライアント・コンピュータ102aは、初期状態INIT.STATE = Working、INIT.WAITING = {}とし、グローバル・トランザクションID(TxID)を以って、対応するサーバ106aのトランザクションの状態管理用のマップTxStateMapに対して、put(TxID,INIT)を実行する。このとき、コミットはしない。この管理用のマップに対するトランザクションは、管理用ローカル・トランザクションと呼ばれる。なお、ここでクライアント・コンピュータ102aとサーバ106aの組み合わせを例にとって説明しているが、実際上、クライアント・コンピュータ102a、102b、・・・102zとサーバ106a、106b、・・・106zの任意の組み合わせがありえることに留意されたい。また、実際上、クライアント・コンピュータ102aのアプリケーション・プログラム404aがサーバに対するトランザクションを実行するが、以下の説明では便宜上、クライアント・コンピュータ102aが実行すると記述する。
【0069】
図10は、照会時の処理、すなわち、mapに対してkeyのバリューを照会する場合の処理のフローチャートを示す図である。図10のステップ1002では、クライアント・コンピュータ102aは、対応するサーバ106aのトランザクション処理プログラム406aに問い合わせして、DataMap.put(key)という問い合わせを行い、その結果のエントリをVに格納する。そして、DataMap.commit()により、コミットする。
【0070】
ステップ1004では、クライアント・コンピュータ102aからの指示で、サーバ102aが、NEW = Vで、Vを一旦NEWにコピーし、NEW.READING.add(TxID)により、データ・マップ(DataMap)410aのREADINGフィールドにTxIDを格納する。
【0071】
ステップ1006では、サーバ106aは、V.WRITING == NULLかどうか判断し、そうでないなら、ステップ1008は、V.WRITINGのトランザクションの終了を待機する。そして、ステップ1010で、V.WRITINGがコミット済みかどうか判断し、もしそうなら、ステップ1012で、NEW.NOW = NEW.NEXTと格納し、NEW.NEXT = NULLとする。そうでなければステップ1014で単に、NEW.NEXT = NULLとする。こうして次にステップ1016に進む。
【0072】
ステップ1006でV.WRITING == NULLであると判断されたなら、直接ステップ1016に進む。
【0073】
ステップ1016では、クライアント・コンピュータ102aは、DataMap.cas(key,V,NEW)をトランザクション処理プログラム406aに指示し、次にトランザクション処理プログラム406aは、DataMap.commit()により、コミットする。
【0074】
サーバ106aは、ステップ1018で、CASが成功したかどうかを判断し、もしそうなら、ステップ1020で、ReadingKeyList.add(key)により、keyをReadingKeyListに追加して、処理を終える。ステップ1018で、CASが成功しなかったと判断されると、処理はステップ1002に戻る。
【0075】
図11は、更新時の処理、すなわち、mapに対してkeyのバリューをv'に更新する場合の処理のフローチャートを示す図である。図11のステップ1102では、クライアント・コンピュータ102aは、トランザクション処理プログラム406aにDataMap.put(key)という問い合わせを行い、するとサーバ106aは、その結果のエントリをVに格納する。そして、DataMap.commit()により、コミットする。
【0076】
ステップ1104では、サーバ106aは、DIRTY = Vで、Vを一旦DIRTYにコピーし、DIRTY.NEXT = v'とセットし、さらに、DIRTY.WRITING = TxIDとセットする。
【0077】
ステップ1106では、サーバ106aは、V.WRITING == TxIDかどうか判断し、そうでないなら、ステップ1108で、V.WRITING == NULLかどうか判断する。もしそうでないなら、ステップ1110で、V.WRITINGのTxに対する終了処理の待機を行う。次にステップ1112では、V.WRITINGがコミット済みかどうか判断し、そうならDIRTY.NOW = V.NEXTとしてステップ1116に進む。V.WRITINGがコミット済みでないなら、直接ステップ1116に進む。一方、ステップ1108で、V.WRITING == NULLであると判断された場合、直接ステップ1116に進む。
【0078】
ステップ1116では、サーバ106aは、DIRTY.READING.remove(TxID)により、DIRTY.READINGからTxIDを除去する。
【0079】
ステップ1118では、サーバ106aは、V.READING.isEmpty()により、V.READINGが空かどうか判断する。もし空であればステップ1122に進み、空でなければステップ1120で、DIRTY.READING中の全トランザクションに対する終了待機処理を行う。
【0080】
こうして、ステップ1106でYESの場合、ステップ1118でYESの場合、あるいはステップ1120に続いて、ステップ1122では、サーバ106aは、DIRTY.READING = {}, DataMap.cas(key,V,DIRTY)及びDataMap.commit()を実行する。
【0081】
ステップ1124では、サーバ106aは、CASが成功したかどうかを判断し、もしそうなら、ステップ1126で、ReadingKeyList.remove(key)で、ReadingKeyListからkeyを除去し、DirtyList.add(DIRTY)により、DirtyListにDIRTYを追加する。一方、CASが成功しなかったと判断したら、処理はステップ1102に戻る。
【0082】
図12は、コミット時の処理のフローチャートを示す図である。コミット時には、ステップ1202で、前の状態であるPrevState.STATEにWorkingがセットされ、新しい状態であるNewState.STATEにCommittedがセットされ、TxStateMap.cas(TxID, PrevState, NewState)を実行した後、TxStateMap.commit()が実行される。
【0083】
次のステップ1204で、サーバ106aは、CASが成功したかどうかを判断し、そうでなければステップ1206でのロールバック処理に行く。ここでCASが失敗したということは、他のトランザクションから強制的にアボートされたことを意味する。
【0084】
一方、CASが成功したなら、ステップ1208で、サーバ106aは、DirtyListのすべてのバリューを選択したかどうかの判断を行う。もしそうなら、ステップ1210で、ReadingKeyList中の全てのバリューを選択したかどうかを判断し、そうでなければ、ステップ1212でReadingKeyList中のCASが成功していないkeyを選択し、ステップ1214で、
V = DataMap.get(key)
NEW = V
V.READING.remove(TxID)
DataMap.cas(key,V,NEW)
DataMap.commit()
を実行し、CASが成功しない限りステップ1212に戻る。CASが成功するとステップ1210に進み、そして、ステップ1210でReadingKeyList中の全てのバリューを選択したと判断されると、処理を終了する。
【0085】
ステップ1208に戻って、DirtyListのすべてのバリューを選択していないと判断されると、サーバ106aは、ステップ1218でDirtyList中の選択していないバリュー(DIRTY)を選択し、ステップ1220で
NEW = DIRTY
NEW.NEXT = NULL
NEW.NOW = DIRTY.NEXT
NEW.WRITING = NULL
を実行し、ステップ1222でDataMap.cas(key,DIRTY,NEW)、DataMap.commit()を実行して、ステップ1208に戻る。
【0086】
図13は、TxIDをグローバル・トランザクションIDとするトランザクションが、TgtTxIDをグローバル・トランザクションIDとするトランザクションの終了を待機する処理のフローチャートを示す図である。
【0087】
ステップ1302では、クライアント・コンピュータ102aは、サーバ102aのトランザクション処理プログラム406aに働きかけて、
WorkingState.STATE = Working
WaitState.STATE = Waiting
WaitState.WAITING = {TgtTxID}
TxStateMap.cas(TxID,WorkingState,WaitState)
TxStateMap.commit()
を実行する。
【0088】
そしてステップ1304で、サーバ106aは、CASが成功したかどうかを判断する。ここでCASが成功しなかったということは、他のトランザクションから強制的にアボートされたということであり、ステップ1306でロールバック処理を行う。
【0089】
CASが成功したと判断されると、サーバ106aは、ステップ1308で、TgtState = TxStateMap.get(TgtTxID)を実行し、次にTxStateMap.commit()を実行する。ここでgetが実行されるのは、TgtTxIDのトランザクションがWaiting、Committed、Rollbacked時のみである。
【0090】
ステップ1310では、サーバ106aは、TgtState.WAITING.contained(TxID)、すなわち、TgtStateのWAITINGに、TxIDが含まれているかどうかを判断する。もしそうでなければ、デッドロックの可能性ありとして、ステップ1306でロールバック処理を行う。
【0091】
ステップ1310で、TgtStateのWAITINGに、TxIDが含まれていると判断されると、ステップ1312で、TgtState.STATEがCommittedまたはRollbackedのどちらかであるかどうかが判断され、もしそうなら、ステップ1322に進んで、サーバ106aは、TxStateMap.cas(TxID,WaitState,WorkingState)とFinishTxID.add(WaitingTxID)を実行し、その結果ステップ1324で、CASが成功したかどうか判断し、もし成功なら処理を終わり、そうでなければ、ステップ1326でロールバック処理を行う。
【0092】
ステップ1312に戻って、TgtState.STATEがCommittedまたはRollbackedのどちらでもないなら、サーバ106aは、ステップ1314で、TgtTxIDはゾンビ、すなわち、長時間Waitingであるかどうか、判断する。もしそうなら、ステップ1318に進み、そこで、下記の処理を行う。
NewTgtState.STATE = Rollbacked
TxStateMap.cas(TgtTxID,TgtState,NewTgtState)
TxStateMap.commit()
【0093】
ステップ1320で、サーバ106aは、CASが成功したかどうか判断し、もし成功ならステップ1322に進み、そうでないなら、ステップ1308に戻る。
【0094】
ステップ1314に戻って、TgtTxIDはゾンビでないと判断されると、ステップ1316に進み、そこで、下記の処理を行う。
PrevWaitState = WaitState
// これは、WaitStateをPrevWaitStateにコピーする処理である。
WaitState.WAITING.addAll(TgtState.WAITING)
// これは、WaitState.WAITINGのすべてのグローバル・トランザクションIDをWaitState.WAITINGに追加する。
TxStateMap.cas(key,prevWaitState,WaitState)
TxStateMap.commit()
TgtTxID = TgtState.tail()
// これは、TgtState.WAITINGの最後にリストされているグローバル・トランザクションIDをTgtTxIDに代入するものである。
そして処理は、ステップ1304に戻る。
【0095】
図14は、ロールバック時の処理のフローチャートを示す図である。図14において、ステップ1402で、前の状態であるPrevState.STATEにWorkingがセットされ、新しい状態であるNewState.STATEにCommittedがセットされ、TxStateMap.cas(TxID, PrevState, NewState)を実行した後、TxStateMap.commit()が実行される。
【0096】
次に、ステップ1404で、サーバ106aは、DirtyListのすべてのバリューを選択したかどうかの判断を行う。もしそうなら、ステップ1406で、ReadingKeyList中の全てのバリューを選択したかどうかを判断し、そうでなければ、ステップ1408でReadingKeyList中のCASが成功していないkeyを選択し、ステップ1410で、
V = DataMap.get(key)
NEW = V
V.READING.remove(TxID)
DataMap.cas(key,V,NEW)
DataMap.commit()
を実行し、CASが成功しない限りステップ1408に戻る。そして、ステップ1210でReadingKeyList中の全てのバリューを選択したと判断されると、処理を終了する。
【0097】
ステップ1208に戻って、DirtyListのすべてのバリューを選択していないと判断されると、サーバ106aは、ステップ1414でDirtyList中の選択していないバリュー(DIRTY)を選択し、ステップ1416で
NEW = DIRTY
NEW.NEXT = NULL
NEW.NOW = DIRTY.NEXT
NEW.WRITING = NULL
を実行し、ステップ1418でDataMap.cas(key,DIRTY,NEW)、DataMap.commit()を実行して、ステップ1404に戻る。
【0098】
次に、図15〜図18の例を参照して、本発明のいくつかの典型的な処理の例を示す。なお、以下では説明の便宜上、データ・マップ(DataMap)におけるNOW、NEXTのバリューは省略する。また、図15〜図18において、sは共有ロック(Shared)、xは排他ロック(eXclusive)をあらわす。
【0099】
まず図15は、Tx1がK1を照会後、コミットする例を示す。図15の1では、クライアント・コンピュータがトランザクションTx1を開始し、これによって、管理マップ412aのKEYにTx1が格納され、STATEがWorkingとなる。
【0100】
図15の2で、Tx1が共有ロックK1を獲得すると、データ・マップ410aのKEYにK1が格納され、データ・マップ410aのREADINGに{Tx1}が格納される。
【0101】
図15の3で、Tx1のコミット処理が行われ、管理マップ412aのSTATEがCommittedになる。
【0102】
図15の4で、Tx1の更なるコミット処理が行われ、データ・マップ410aのREADINGが{}になる。
【0103】
図16は、Tx1がK1を照会中、Tx2がK1の更新を試行し、Tx1のコミット後に処理されるという例を示す。
【0104】
図16の1では、Tx1がK1を照会中であることを示す。図16の2では、Tx2が共有ロックK1を獲得しようとするが、Tx1がK1を照会中なので、Tx2の照会はブロックされる。管理マップ412aのKEY = Tx2のエントリのWAITINGには、{Tx1}が入る。
【0105】
図16の3では、Tx1のコミット処理終了後Tx2が照会可能となり、図16の4では、Tx2が共有ロックK1を獲得再開する。これに応答して、管理マップ412aのKEY = Tx2のエントリのSTATEがWorkingになり、WAITINGは{}になる。
【0106】
図16の5では、Tx2の更新処理が開始され、データ・マップ410aのKey = K1に対応するWRITINGにTx2が格納される。
【0107】
図17は、Tx1の終了をTx2が待機し、Tx2の終了をTx3が待機する場合、Tx1が終了時にTx2が稼動を開始し、Tx3が依然としてTx2を待機する例を示す。
【0108】
図17の1では、管理マップ412aのエントリが示すように、Tx1のコミットを、Tx2が待機中である。図17の2では、Tx2が照会中のK2をTx3が更新開始する。ここでTx3は、Tx2がTx1待ちと認識する。
【0109】
図17の3では、Tx3がTx1を待機中になる。このことは、管理マップ412aのKEY = Tx3に対応する、WAITINGの{Tx2,Tx1}というエントリによって示される。
【0110】
図17の4は、Tx1がコミットされて終了した後に、Tx3がTx2待ちになる様子を示す。
【0111】
図18は、Tx1、Tx2、Tx3でデッドロックした場合、Tx1がロールバックする処理の例を示す。図18の1では、Tx1、Tx3がTx1を待機中になる。図18の2では、Tx1がTx3の照会中のバリューの更新を試みる。
【0112】
しかし、管理マップ412aのエントリから見て取れるように、Tx3に対応するエントリのWAITINGにTx1が含まれるため、図18の3に示すように、Tx1はロールバックする。
【0113】
すると、図18の4に示すように、Tx1のロールバック後、管理マップ412aのTx2とTx3のエントリのWAITINGのフィールドからTx1が消去され、Tx3はTx2待ちになる。この際、Tx1のSTATEをRollbackedにする前に、Tx2とTx3がTx1のSTATEを照会した場合は、すべてのトランザクションがロールバックするが、原子性は保障される。
【0114】
以上、特定のハードウェア及びソフトウェアのプラットアフォームの上で本発明の実施例を説明してきたが、本発明は、任意のコンピュータのハードウェア及びプラットフォームで実施可能であることを、この分野の当業者なら理解するであろう。
【符号の説明】
【0115】
102 クライアント・コンピュータ
106 サーバ
202 主記憶
204 CPU
206 メインメモリ
206 主記憶
210 ハードディスク・ドライブ
306 CPU
308 主記憶
310 ハードディスク・ドライブ
404 アプリケーション・プログラム
406 トランザクション処理プログラム
408 KVSプログラム
410 データ・マップ
412 管理用マップ

【特許請求の範囲】
【請求項1】
複数のサーバをもち、該各サーバが排他制御機構を有し、前記各サーバにおけるトランザクション原子性・分離性が保障される分散キーバリューストア・システムにおいて、各サーバ上でのローカル・トランザクション処理を組み合わせることで、全サーバ上でのトランザクション原子性・分離性を保つグローバル・トランザクション処理を実現する方法であって、
コンピュータの処理によって、キーをグローバル・トランザクションID、バリューを{グローバル・トランザクションの状態、終了待ちグローバル・トランザクションIDリスト}とする管理用マップを全てのグローバル・トランザクションの開始前に、あらかじめ、用意するステップと、
前記コンピュータの処理によって、ある処理対象グローバル・トランザクションを開始時に、前記複数のサーバのうちの1つのサーバで、前記管理用ローカル・トランザクションを開始するステップと、
前記コンピュータの処理によって、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションのIDをキーとし、{workingという状態,null}をバリューとするキー・バリュー・ペアを前記管理用マップに挿入するステップと、
前記コンピュータの処理によって、前記管理用ローカル・トランザクションで、前記管理用マップにおいて、処理対象グローバル・トランザクションIDをキーとするバリューを、{waitingという状態, 処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト}に更新して、前記管理用ローカル・トランザクションをコミットするステップを有する、
分散キーバリューストア・システムの制御方法。
【請求項2】
前記コンピュータの処理によって、処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト内の末尾の終了待ちグローバル・トランザクションIDを、管理用マップのキーとして管理する前記サーバ上で、ロック開放待ちトランザクションを開始し、終了待ちグローバル・トランザクションIDをキーするバリューを照会するステップと、
前記コンピュータの処理によって、前記管理用マップにおいて、前記照会したバリューが存在しない、もしくは、バリューにおける終了待ちグローバル・トランザクションの状態が、committedまたはabortedであることに応答して、前記ロック開放待ちトランザクションをコミットし、管理用ローカル・トランザクションを再度開始して、グローバル・トランザクションIDをキーとするバリューを、{workingという状態,null}に更新し、ロックの競合が終了したことを通知するステップをさらに有する、
請求項1に記載の方法。
【請求項3】
前記コンピュータの処理によって、終了待ちグローバル・トランザクションIDを管理用マップのキーとして管理する前記サーバ上で、ロック開放待ちトランザクションを開始し、終了待ちグローバル・トランザクションIDをキーとするバリューを照会するステップと、
前記コンピュータの処理によって、前記管理用マップにおいて、前記照会したバリューが{waitingという状態, 終了待ちグローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト}の場合、
前記ロック開放待ち用ローカル・トランザクションをコミットし、
処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリストに終了待ちグローバル・トランザクションの終了待ちグローバル・トランザクションIDリストを追加して、処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリストを生成し、
再度管理用ローカル・トランザクションを開始し、
処理対象グローバル・トランザクションIDをキーとするバリューを、{waitingという状態, 処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリスト}に更新し、
管理用ローカル・トランザクションをコミットし、
処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリストの末尾のグローバル・トランザクションIDを終了待ちグローバル・トランザクションIDとして、請求項2におけるグローバル・トランザクションの終了待機処理を行うステップをさらに有する、
請求項1に記載の方法。
【請求項4】
前記処理対象グローバル・トランザクションをコミットする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{committed,{}}に更新し、前記管理用ローカル・トランザクションをコミットするステップをさらに有する、請求項1に記載の方法。
【請求項5】
前記処理対象グローバル・トランザクションをロールバックする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{ aborted,{}}に更新し、前記管理用ローカル・トランザクションをコミットするステップをさらに有する、請求項1に記載の方法。
【請求項6】
複数のサーバをもち、該複数のサーバが排他制御機構を有し、前記サーバにおけるトランザクション原子性が保障される分散キーバリューストア・システムにおいて、各サーバ上でのローカル・トランザクション処理を組み合わせることで、全サーバ上でのトランザクション原子性・分離性を保つグローバル・トランザクション処理を実現するプログラムあって、
前記システムに、
キーをグローバル・トランザクションID、バリューを{グローバル・トランザクションの状態、終了待ちグローバル・トランザクションIDリスト}とする管理用マップを全てのグローバル・トランザクションの開始前に、あらかじめ、用意するステップと、
前記コンピュータの処理によって、ある処理対象グローバル・トランザクションを開始時に、前記複数のサーバのうちの1つのサーバで、前記管理用ローカル・トランザクションを開始するステップと、
前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションのIDをキーとし、{workingという状態,null}をバリューとするキー・バリュー・ペアを前記管理用マップに挿入するステップと、
前記管理用ローカル・トランザクションで、前記管理用マップにおいて、処理対象グローバル・トランザクションIDをキーとするバリューを、{waitingという状態, 処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト}に更新して、前記管理用ローカル・トランザクションをコミットするステップを実行させる、
プログラム。
【請求項7】
処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト内の末尾の終了待ちグローバル・トランザクションIDを、管理用マップのキーとして管理する前記サーバ上で、ロック開放待ちトランザクションを開始し、終了待ちグローバル・トランザクションIDをキーするバリューを照会するステップと、
前記管理用マップにおいて、前記照会したバリューが存在しない、もしくは、バリューにおける終了待ちグローバル・トランザクションの状態が、committedまたはabortedであることに応答して、前記ロック開放待ちトランザクションをコミットし、管理用ローカル・トランザクションを再度開始して、グローバル・トランザクションIDをキーとするバリューを、{workingという状態,null}に更新し、ロックの競合が終了したことを通知するステップをさらに有する、
請求項6に記載のプログラム。
【請求項8】
終了待ちグローバル・トランザクションIDを管理用マップのキーとして管理する前記サーバ上で、ロック開放待ちトランザクションを開始し、終了待ちグローバル・トランザクションIDをキーとするバリューを照会するステップと、
前記管理用マップにおいて、前記照会したバリューが{waitingという状態, 終了待ちグローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト}の場合、
前記ロック開放待ち用ローカル・トランザクションをコミットし、
処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリストに終了待ちグローバル・トランザクションの終了待ちグローバル・トランザクションIDリストを追加して、処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリストを生成し、
再度管理用ローカル・トランザクションを開始し、
処理対象グローバル・トランザクションIDをキーとするバリューを、{waitingという状態, 処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリスト}に更新し、
管理用ローカル・トランザクションをコミットし、
処理対象グローバル・トランザクションの新たな終了待ちグローバル・トランザクションIDリストの末尾のグローバル・トランザクションIDを終了待ちグローバル・トランザクションIDとして、請求項6におけるグローバル・トランザクションの終了待機処理を行うステップをさらに有する、
請求項6に記載のプログラム。
【請求項9】
前記処理対象グローバル・トランザクションをコミットする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{committed,{}}に更新し、前記管理用ローカル・トランザクションをコミットするステップをさらに有する、請求項6に記載のプログラム。
【請求項10】
前記処理対象グローバル・トランザクションをロールバックする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{ aborted,{}}に更新し、前記管理用ローカル・トランザクションをコミットするステップをさらに有する、請求項6に記載のプログラム。
【請求項11】
複数のサーバをもち、該複数のサーバが排他制御機構を有し、前記サーバにおけるトランザクション原子性が保障される分散キーバリューストア・システムにおいて、各サーバ上でのローカル・トランザクション処理を組み合わせることで、全サーバ上でのトランザクション原子性・分離性を保つグローバル・トランザクション処理を実現するシステムあって、
メモリと、
キーをグローバル・トランザクションID、バリューを{グローバル・トランザクションの状態、終了待ちグローバル・トランザクションIDリスト}とする管理用マップを全てのグローバル・トランザクションの開始前に、前記メモリにあらかじめ、用意する手段と、
前記コンピュータの処理によって、ある処理対象グローバル・トランザクションを開始時に、前記複数のサーバのうちの1つのサーバで、前記管理用ローカル・トランザクションを開始する手段と、
前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションのIDをキーとし、{workingという状態,null}をバリューとするキー・バリュー・ペアを前記管理用マップに挿入する手段と、
前記管理用ローカル・トランザクションで、前記管理用マップにおいて、処理対象グローバル・トランザクションIDをキーとするバリューを、{waitingという状態, 処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト}に更新して、前記管理用ローカル・トランザクションをコミットする手段を有する、
システム。
【請求項12】
処理対象グローバル・トランザクションの終了待ちグローバル・トランザクションIDリスト内の末尾の終了待ちグローバル・トランザクションIDを、管理用マップのキーとして管理する前記サーバ上で、ロック開放待ちトランザクションを開始し、終了待ちグローバル・トランザクションIDをキーするバリューを照会する手段と、
前記管理用マップにおいて、前記照会したバリューが存在しない、もしくは、バリューにおける終了待ちグローバル・トランザクションの状態が、committedまたはabortedであることに応答して、前記ロック開放待ちトランザクションをコミットし、管理用ローカル・トランザクションを再度開始して、グローバル・トランザクションIDをキーとするバリューを、{workingという状態,null}に更新し、ロックの競合が終了したことを通知する手段をさらに有する、
請求項11に記載のシステム。
【請求項13】
前記処理対象グローバル・トランザクションをコミットする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{committed,{}}に更新し、前記管理用ローカル・トランザクションをコミットする手段をさらに有する、請求項11に記載のシステム。
【請求項14】
前記処理対象グローバル・トランザクションをロールバックする場合、前記管理用ローカル・トランザクションで、前記処理対象グローバル・トランザクションIDをキーとするバリューを{ aborted,{}}に更新し、前記管理用ローカル・トランザクションをコミットする手段をさらに有する、請求項11に記載のシステム。

【図1】
image rotate

【図2】
image rotate

【図3】
image rotate

【図4】
image rotate

【図5】
image rotate

【図6】
image rotate

【図7】
image rotate

【図8】
image rotate

【図9】
image rotate

【図10】
image rotate

【図11】
image rotate

【図12】
image rotate

【図13】
image rotate

【図14】
image rotate

【図15】
image rotate

【図16】
image rotate

【図17】
image rotate

【図18】
image rotate


【公開番号】特開2013−33345(P2013−33345A)
【公開日】平成25年2月14日(2013.2.14)
【国際特許分類】
【出願番号】特願2011−168461(P2011−168461)
【出願日】平成23年8月1日(2011.8.1)
【公序良俗違反の表示】
(特許庁注:以下のものは登録商標)
1.JAVA
【出願人】(390009531)インターナショナル・ビジネス・マシーンズ・コーポレーション (4,084)
【氏名又は名称原語表記】INTERNATIONAL BUSINESS MACHINES CORPORATION