第8回 J2EEのトランザクション処理


 J2EEのトランザクション

 ここから、いよいよJ2EEのトランザクションの解説に入ります。J2EEには、プログラマーがトランザクションを詳細まで意識しなくてもよい実装が行われています。

 

 J2EEのトランザクション処理の特徴

 プログラマーが「大衆化」し、その意識とスキルが変化し、同時に分散トランザクションの高度な処理が、ネットワーク・アプリケーションでも必要となるケースがあり得ることを少し詳しく見てきましたが、それには訳があります。J2EEのアプローチは、こうした問題に対する、極めて興味深い、かつ現実的な解答を提供しているからです。J2EEのトランザクション処理の最大の特徴の1つは、プログラマーが面倒なトランザクションのコードを書かなくても、コンテナが自動的にトランザクション処理をしてくれることにあります。

 J2EEでは、プログラマーがトランザクション処理に精通して、正しいトランザクション処理のコードを生成することを期待するのをやめて、マシンがそれをカバーするようにしたのだと考えてもいいかもしれません。プログラマーがトランザクションを知らなくても、トランザクションはJ2EEがしっかりと面倒を見るというわけです。こうした見方は、少し意地悪に見えるかもしれませんが必ずしもそうではありません。交通量が多くて車のスピードも速い基幹道路の交差点の24時間の交通整理を、人間がやるより信号機を設置した方がよいと考えるのは、必ずしも人間不信とはいえません。まして、その交通整理をおぼつかない子どもがやっていたら、ドライバは怒りだすでしょう。

 J2EEでは、エンティティ・ビーンでもセッション・ビーンでも、このContainer-Managed Transactionsの機能を使うことができます。正確にいえば、データベースとの結びつきが強いエンティティ・ビーンでは、このコンテナ管理のトランザクションしか利用することはできません。別のいい方をすれば、エンティティ・ビーンを使う限り、トランザクションは、すべてコンテナが面倒を見ることができるので、トランザクションをあえて意識する必要はありません。これは、J2EEの非常に大きな特徴です。

 ここでは、エンティティ・ビーンで、データの永続性を保証するContainer-ManagedPersistent(CMP)が、EJB1.0では、オプションであったことを思い出してください。データベースとの同期を自動化しようとする、CMP2.0は、EJB2.0の中心的な目標の一つだと思いますが、ビーンとコンテナというJ2EEのアイデアの、非常に早い時期から、トランザクションへの対応が、J2EEシステムの大きな目標として意識され、早くからその実装が成功裏に行われたのは、確かだと思います。

 

 メソッドの挟み込みとContainer-Managed Transactions

 デフォルトのContainer-Managed Transactionsでは、コンテナは、ビーンのメソッドが始まる直前にトランザクションを開始し、メソッドが終了したらトランザクションをコミットします。ここでは、これまで何度か見てきた、次のような、コンテナによるメソッドの書き換えとメソッドの挟み込みが、うまく使われています。

 第6回で、次のような例を紹介しました。

public String sayHello() throws RemoteException { // Remoteメソッドである。
  ............
  HelloEJB helloejb = (HelloEJB) ............ ; // 元のEJBクラスのインスタンス
  ............
  container.preInvoke(...); // メソッド呼び出しの前処理
  String s = helloejb.sayHello(); // 元のEJBクラスのメソッド呼び出し
  container.postInvoke(...); // メソッド呼び出しの後処理
  ............
  return s;
}

 このように、EJBプログラマーが定義した、HelloEJBクラスのsayHelloメソッドは、コンテナの中では、上のリストのように、同名の、しかしながらRemoteのsayHelloメソッドに書き換えられ、その前後の、preInvokeメソッドとpostInvokeメソッドによって挟み込まれます。

 予想がつくと思いますが、J2EEでは、このpreInvokeの中で、トランザクションの準備を行うpreInvokeTxメソッドが呼び出され、postInvokeの中で、トランザクションの後処理を行うpostInvokeTxメソッドが呼び出されます。

 

 Deploy時に、トランザクションの属性を宣言する

 このように、Container-Managed Transactionsは、1つ1つのメソッドにトランザクション処理をするということが基本になっています。しかも、その処理の条件は、ビーンの配置時に、それぞれのメソッドについてトランザクション属性を指定することで、細かなコントロールが可能です。画面1はエンティティ・ビーンの、画面2は、セッション・ビーンのContainer-Managed Transactionsの設定画面です。1つ1つのメソッドに対して、トランザクションの属性が設定されているのが分かると思います。デフォルトでは、“Required”という属性が選択されています。

画面1 

画面2 

 

 トランザクションのscopeとトランザクション属性

 たいていの場合には、この“Required”で十分だと思いますが、J2EEでは、トランザクションについて細かな属性が定義されています。

 最初に確認したいのは、トランザクションには、スコープがあるということです。例えば、ビーンAでトランザクションが開始され、その中でメソッドAが呼び出されたとします。このとき、さらにメソッドAの中でビーンBのメソッドBが呼び出されたとしましょう。メソッドBのトランザクションは、メソッドAのトランザクションの範囲の中にあるのでしょうか? それとも、メソッドBには、新しいトランザクションが必要なのでしょうか?実は、それぞれのメソッドへのトランザクション属性の設定によって、トランザクションの範囲はコントロールすることが可能です。

 J2EEのトランザクション属性には、次の6種類があります。

  • Required
  • RequireNew
  • Mandatory
  • NotSupported
  • Supports
  • Never

 次のページから、それぞれのトランザクション属性の特徴を見ておきましょう。最初のいくつかについては、対応するコードの一部を引用しておきました。

3/5

J2EEの基礎(第8回)
  コンピューティングにおけるトランザクションの必要性
  トランザクションの基礎を知る
J2EEのトランザクション
  トランザクション属性の特長
  トランザクション属性

連載内容
J2EEの基礎
  第1回 Java Pet Storeで、J2EEを体験する(1)
  第2回 Java Pet Storeで、J2EEを体験する(2)
 

第3回 J2EEアプリケーションと配置(deployment)

  第4回 J2EEアプリケーションを構成するコンポーネント
  第5回 データベースのブラウザを作る
  第6回 EJBにおけるコンテナとコンポーネント
  第7回 J2EEのセキュリティのキホンを知る
第8回 J2EEのトランザクション処理


連載記事一覧




Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間