サンプル 4b は、server1
と server2
を使用した分散型 2 フェーズ コミット トランザクション管理の使用法を示しています。また、このサンプルは、EjbClient.java
および BalanceBean.java
に含まれている save
および spend
メソッドの実装で示されているとおり、クライアント区分トランザクションとコンテナ管理トランザクションの両方を使用します。
メモ このサンプルはリレーショナル データベースを使用しますが、独創的な動作はしませ
ん (スキーマについては、第 7 章の「サンプル 2」セクションを参照してください)。
サンプル 4b を実行するには、複数の接続をサポートしているデータベースとドライ
バを使用する必要があります。特定のデータ ソース フォーマットに従って、使用して
いるデータソース情報を |
最初に META-INF/ejb-jar.xml
ファイルを開き、次の env-entry
要素を調べます。
save.ejb.transactionAttribute
が mandatory
に設定されていること。これは、save メソッドが呼び出されたときにトランザクションが実行されていなければならないことを示します。このサンプルでは、EjbClient.java
プログラムの save
メソッドがトランザクションを管理します。
spend.ejb.transactionAttribute
が required
に設定されていること。これは、spend
メソッドが呼び出されたときにトランザクションがないと、EJB エンジンがトランザクションを開始することを示します。
JRun のルート ディレクトリ/samples/sample4b
ディレクトリにある deploy2.properties
ファイルを調べます。deploy2.properties
ファイルは、server2
により使用されます。次のエントリに注意してください。
sample4b.BalanceHome.maxValue=1000
sample4b.BalanceHome.minValue=-1000
これらの 2 つのプロパティは、残高の有効範囲を指定します。server2
における最小値は -1000、最大値は 1000 です。最小値または最大値に達すると、例外となります。Server2
の BalanceBean
は、残高をプロパティ ファイルに設定されている値と照合してチェックします。server2
で制限を超えると例外となり、server1
でもトランザクションがロールバックされます。
詳細については、『JRun によるアプリケーションの開発』を参照してください。
まず、呼び出しをより単純に、また理解しやすくするために JNDI コンテキストをカスタマイズします。JRun のルート ディレクトリ/samples/sample4b/client
ディレクトリに移動して EjbClient.java
ファイルを開きます。login
メソッドにより、クライアントがポート 2323 (server1
) でリスニングしているサーバへの context
参照を設定した場所が確認できます。次に、クライアントは、ポート 2324 (server2
) で受信しているサーバに対する context 参照を設定し、sample4b.BalanceHome
を BalanceHome2
に結合します。次の図に示すように、これによって "server1" のsample4b.BalanceHome
と "server2"の sample4b.BalanceHome
を区別します。
EjbClient.java
の save
メソッドに注目してください。server1
および server2
の残高は save
メソッドによって更新されます。save
は 2 つの Balance
インスタンスを作成します。これらは各サーバにそれぞれ関連付けられます。transaction.begin
を実行します。これは公開記述子の save.ejb.transactionAttribute
設定に必要です。
次に EjbClient.save
メソッドは、Balance
の両方のインスタンスに対して save(amount)
を呼び出します。いずれかの呼び出しで例外が発生した場合、トランザクションがロールバックされ、両方のサーバの残高が更新されません。例外が発生しない場合は、transaction.commit
が呼び出されます。そのため、server2
で残高が最小値または最大値に達すると、transaction.rollback
が呼び出されて server1
と server2
の同期を取ります。
EjbClient.java
の spend
メソッドを調べます。EjbClient.java
の save
メソッドはサーバごとに BalanceBean.save
を呼び出したのに対し、EjbClient.java
の spend
メソッドは BalanceBean.spend
を一度だけ呼び出します。BalanceBean.spend
は、登録されている別の BalanceBean
を検索するためです。見つかると、BalanceBean.spend
メソッドが呼び出されます。
次は、JRun のルート ディレクトリ/samples/sample4b/ejbeans/BalanceBean.java
ファイルの spend
メソッドに注目してください。spend
メソッドは自らの残高を更新しますが、次のコードの抜粋のとおり、server2
の残高も更新します。
if (_balance2 != null)
{ _balance2.spend(value);}
server1
がどのように server2
を認識するかを理解するには、BalanceBean.connect
メソッドに注目します。次のコードが表示されます。
...
try { Properties environment = _context.getEnvironment(); String host = environment.getProperty(EjiptProperties.CLASS_SERVER_HOST); int port = Integer.parseInt(environment.getProperty("balance2Port")); Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "allaire.ejipt.ContextFactory"); properties.setProperty(Context.PROVIDER_URL, "ejipt://" + host + ":" + port); BalanceHome home = (BalanceHome)(new InitialContext(properties)).lookup ("sample4b.BalanceHome"); _balance2 = createBalance(home, 123); } catch (NumberFormatException format) { // ポート情報なし、接続は不要です。 } catch (Exception exception) { ResourceManager.getLogger().logException ("Failed to contact other server", exception); } ...
このコードは、関連する deploy.properties
ファイルで、balance2Port
という名前のプロパティをチェックします。JRun のルート ディレクトリ/samples/sample4b
にあるdeploy.properties
ファイルには、次のエントリが含まれています。
sample4b.BalanceHome.balance2Port=2324
コードで createBalance
を呼び出します。これによって server2
のリモート インターフェイスへの参照が返されます。BalanceBean.getBalance2
メソッドは、ポート 2324 で受信しているサーバ (以前 server2
として参照された) の BalanceHome
に対する参照を単に取得します。
make
ファイルは、ejipt.ejbDirectory
プロパティを使用して、第 2 のサーバ インスタンスの /deploy
および /runtime
ディレクトリを指定します。
サンプルを実行するには、コマンド プロンプトを開いて RMID のシェルを起動します (このサンプルはフェイルセーフ モードで実行するので RMID が必要です)。環境変数を設定し、次のコマンドを入力して RMID を開始します。
bash$ make rmid
別のコマンド プロンプトとシェルを開きます。次のコマンドを入力します。
bash$ make jars
bash$ make deploy2 bash$ make start2.
make deploy2
および make start2
コマンドは、両方のサーバを展開または起動します。次に make run
を実行してクライアントを起動します。サンプルが終了したら、make stop2
を実行して両方のサーバを停止してください。