2012年12月3日月曜日

XADisk を使用してファイルシステムにトランザクションを活用する

はじめに

サーバー・サイドのアプリケーションやデスクトップ・アプリケーションを含め、多くの Java アプリケーションでは、重要なデータをファイルシステムやデータベース、その他の情報システムに保持します。そうした重要なデータを安全かつ確実に扱えるように、アプリケーションの開発者はそれらの情報システムにトランザクションを使用してアクセスする手段を求めることがよくあります。典型的なトランザクションは、よく知られている ACID 特性 (Atomicity (原子性)、Consistency (一貫性)、Isolation (独立性)、Durability (永続性)) を備えています。

最近のほとんどのデータベースはトランザクションをサポートしています。しかしファイルシステムの場合には、トランザクションを利用できないか、あるいは Java アプリケーションにトランザクションを統合することが困難です。トランザクションを利用しようとしても、一連のファイル操作やディレクトリー操作とトランザクションとの関連付けが不可能になったり非常に困難になったりします。しかしトランザクションを使用しないと、アプリケーションが異常終了した場合や、同じデータ・セットに同時にアクセスする場合、部分的な変更が目に見える状態になった場合などに予想外の結果が生ずるなどのリスクがあります。

この記事では、オープンソースの総合的なトランザクション・システムである XADisk を紹介します。XADisk を利用すると、Java アプリケーションや Java EE アプリケーションからトランザクションを使用してファイルシステムにアクセスできるようになります。いくつかの単純な API を利用することで、OS に何もインストールすることなく任意の JVM に XADisk をデプロイすることができます。いったん XADisk がデプロイされると、アプリケーションは XADisk の API を呼び出すことで、さまざまなファイル I/O 操作をトランザクションの中で行えるようになります。

XADisk は他にも多くの機能を備えています (XA トランザクション、JCA への完全準拠、インバウンド・メッセージングなど)。この記事では入門レベルの内容を紹介するため、それらの機能については説明しません。

XADisk の基本

XADisk はアプリケーションとファイルシステムとの間のレイヤーであると考えることができます。XADisk 自体はファイルシステムの実装ではありません。XADisk は多様なファイルシステム (NTFS、FAT、ext3 など) で動作することができるため、アプリケーションは XADisk を使用することにより、トランザクションを使用してそれらのファイルシステムにアクセスできるようになります。アプリケーションは XADisk の API を呼び出すことで、さまざまな I/O 操作を実行することができ、それらの I/O 操作をまとめて 1 つのトランザクションとしてコミットしたりロールバックしたりすることができます。

XADisk は Java で作成されており、Java 5 以降のバージョンで実行可能です。XADisk を実行できるアプリケーションとしては、あらゆる種類の Java アプリケーション、Apache Tomcat などの Java サーバーで実行する Web アプリケーション、Java EE サーバーで実行する Java EE アプリケーション、等々があります。

XADisk を使用する単純な例として、ある 1 つの Java アプリケーションを考えてみてください。このアプリケーションでは、F1 という新しいファイルを作成し、F2 という別のファイルから F1 に何らかのデータを書き込み、F2 を削除します。XADisk を使用すると、先ほど触れた通常の ACID 特性を保証した上で、この 3 つの操作を 1 つのトランザクション内で実行することができます。たとえ処理途中でアプリケーションが異常終了したとしても、XADisk によって ACID 特性が保証されます。

XADisk はファイルやディレクトリーに対し、以下のようにさまざまな操作をサポートしています。

  • ファイル — 作成、削除、移動、コピー、切り詰め、読み取り、書き込み、存在確認、長さ取得
  • ディレクトリー — 作成、削除、移動、子の一覧表示、存在確認

XADisk を使用する場合、アプリケーションとターゲットのファイルシステムが同じマシン上にある必要はありません。アプリケーションは、同じ JVM 上に XADisk がデプロイされている場合と同じように、リモートから XADisk の API を呼び出すことができます。

この記事のこれから先では、任意の Java アプリケーションで XADisk を使い始めるための簡単な手順について説明します。

XADisk を使用する

起動プロセス

XADisk による I/O 操作を呼び出す前に、JVM 内で XADisk のインスタンスを起動します。同じ JVM の中に複数の XADisk インスタンスが存在することができ、各 XADisk インスタンスは個別に独自の状態を持ちます。この記事では、そうした XADisk インスタンスの 1 つを起動して呼び出す方法について説明します。

任意の JVM で XADisk を起動することができるため、単純な Java プログラムから JBoss などの Java EE サーバーや Tomcat などの Web サーバーに至るまで、さまざまな Java 環境で XADisk を使用することができます。

XADisk インスタンスを起動するためには、システム環境に以下のものがインストールされている必要があります。

  1. Java 5 またはそれ以降のバージョン
  2. XADisk.jar (http://xadisk.java.net/ からダウンロードすることができます)
  3. JCA 1.5 Jar (http://download.java.net/maven/1/javax.resource/jars/connector-api-1.5.jar からダウンロードすることができます)

XADisk は起動の際に、XADisk 自身のさまざまな構成プロパティーを設定するための 1 つの構成オブジェクトを受け付けます。これらの構成プロパティーの大部分には、デフォルト値が設定されています。必須のプロパティーは SystemDirectory と InstanceId のみです。リスト 1 に示すように、構成コンストラクターは、この 2 つの構成プロパティーを受け付けます。SystemDirectory は XADisk が機能する上で必要なすべての成果物 (トランザクション・ログなど) を保持するためのディレクトリーです。InstanceId は JVM 内にある XADisk インスタンスを一意に識別します。


リスト 1. XADisk インスタンスを構成して初期化する
String XADiskSystemDirectory ="/home/systems/XADiskSystem1";  StandaloneFileSystemConfiguration configuration =       new StandaloneFileSystemConfiguration(XADiskSystemDirectory, "instance-1");  XAFileSystem xaf = XAFileSystemProxy.bootNativeXAFileSystem(configuration);  xaf.waitForBootup(10000L);  

上記のシーケンスによって XADisk インスタンスの構成が完了し、起動プロセスの完了待ち状態に入ります。起動が完了すると、同じ JVM 上のアプリケーションで、またはリモートの JVM 上のアプリケーションで、この XADisk インスタンスを使用できるようになります。

XAFileSystem 型を参照することによって XADisk インスタンスの呼び出し処理が開始されることに注意してください。XAFileSystemの参照は以下の方法で取得することができます。

  1. リスト 1 に示すように、起動の際に取得する方法
  2. リスト 2 に示すように、JVM の任意の場所から instanceId を使用して取得する方法

リスト 2. 同じ JVM 内で XADisk インスタンスに対する XAFileSystem の参照を取得する
XAFileSystem xaf = XAFileSystemProxy.getNativeXAFileSystemReference("instance-1");  

  1. リスト 3 に示すように、リモート・アプリケーションによって取得する方法

リスト 3. リモートの JVM で XADisk インスタンスに対する XAFileSystem の参照を取得する
XAFileSystem xaf = XAFileSystemProxy.getRemoteXAFileSystemReference("10.30.9.200", 5151);  /*the parameters are the serverAddress and serverPort configuration properties   used during booting of the remote XADisk instance. Note that remoting to   an XADisk instance is disabled by default and can be enabled   using configuration.setEnableRemoteInvocations(true) during bootup*/  

I/O 操作を呼び出す

これで XADisk インスタンスを用意できたので、ファイルやディレクトリーに対してトランザクション処理を行うことができます。

XAFileSystem の参照を取得してしまえば、ターゲットの XADisk インスタンスが同じ JVM 上で実行されている場合もリモートの JVM で実行されている場合も、XADisk の API を呼び出すための方法は同じです。

ファイルやディレクトリーの操作は 1 つのトランザクションの中で行われるため、まず Session オブジェクトを作成することでトランザクションを開始します (リスト 4)。


リスト 4. セッションを作成してトランザクションを開始する
Session session = xaf.createSessionForLocalTransaction();  

セッションを作成すると、必要に応じて I/O 操作を実行することができます。ファイルやディレクトリーを操作するための XADisk の API は単純です。リスト 5 にその例をいくつか示しています。


リスト 5. ファイルやディレクトリーを操作するための XADisk の API を呼び出す
File f = new File("/testAPIs/test.txt");  if(session.fileExists(f)) {      XAFileInputStream xis = session.createXAFileInputStream(f);      for (int i = 0; i < 100; i++) {          byte a = (byte) xis.read();          if( a== -1) {              break;          }          System.out.print(a);       }      xis.close();      session.moveFile(f, new File("/testAPIs/test.txt___" + System.currentTimeMillis()));  }  else {      //use false below to create file, true for directory      session.createFile(f, false);       //use false below for tiny write operations, true otherwise       XAFileOutputStream xafos = session.createXAFileOutputStream(f, false);       byte[] buffer = new byte[100];       for (int i = 0; i < 100; i++) {          buffer[i] = i*i;       }       xafos.write(buffer);       xafos.close();  }  /* You can do more operations here, by calling Session APIs   for reading/writing/creating/deleting/updating/copying/moving files   and directories. For details, please see the XADisk JavaDoc for   interface named XADiskBasicIOOperations.*/  

すべての I/O 操作が完了すると、単純にセッション・オブジェクトを呼び出すことで、そのトランザクションをコミット (またはロールバック) することができます (リスト 6)。


リスト 6. セッションと関連付けられたトランザクションをコミット (またはロールバック) する
//commit the transaction  session.commit();  //or rollback the transaction  session.rollback();  

新しいトランザクションを開始するためには、新規 Session オブジェクトを作成し、リスト 5 と同じ手順に従います。

インスタンスを停止する

JVM 内の任意の場所から XADisk インスタンスを停止することができます (リスト 7)。


リスト 7. 同じ JVM から XADisk インスタンスを停止する
XAFileSystem xaf = XAFileSystemProxy.getNativeXAFileSystemReference("instance-1");  xaf.shutdown();  

まとめ

重要なデータをファイルシステムに保持するアプリケーションでは、ファイルシステムにトランザクションを使用すると大きなメリットがあります。XADisk は、無料で利用できるオープンソースのソリューションであり、XADisk を利用すると、アプリケーションはトランザクションを使用してファイルシステムを操作できるようになります。XADisk には単純な API が用意されており、その API を利用して XADisk インスタンスを初期化したり、ファイルやディレクトリーに対してさまざまな操作を実行したり、トランザクションを管理したりすることができます。

0 件のコメント:

コメントを投稿