GFv2の XA を使う! PART2 JTA を利用した Web アプリケーションへのコードの実装

29 8 月, 2008 (15:08) | GlassFish, OpenSource

前回は、 JTA を実装した Web アプリケーションを開発するための環境を用意する記事を執筆いたしました。
今回は、いよいよ環境準備が整ったというところで、具体的に、 "どうやって Web アプリケーションへコードを記述すれば良いのか ?" について、執筆して行きたいと思います。


それでは早速!

通常、 Transaction の取得は、 javax.naming.InitialContext からルックアップする手法を用います。
その AppServer が管理しているシステムリソースから Transaction オブジェクトを取得する方法には二つあります。ひとつは、 JavaEE 標準の、 javax.annotation.Resource を利用することで、 Transaction オブジェクトをインジェクションさせる方法と、もうひとつは、従来どおりのネィティブな方法で、 Transaction オブジェクト をルックアップする方法です。


それぞれ以下に、サンプルコードを提示します。

1、javax.annotation.Resource を利用し、 javax.transaction.UserTransaction をインジェクションする。

@Resource javax.transaction.UserTransaction utx;
2、ネィティブなコードで javax.transaction.UserTransaction を javax.naming.InitialContext からルックアップする。

try {
final Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
final Context ctx = new InitialContext(env);
final UserTransaction utx = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
ctx.close();
} catch(NamingException ex) {
Logger.getLogger(ClassName.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
}

※上記コードにて、Context.INITIAL_CONTEXT_FACTORY に指定している名称は、 GlassFish で使用する時にのみ、有効です。

上記2とおりのコードを実装することにより、トランザクションオブジェクトを取得することができます。
取得したオブジェクトにある、それぞれ begin(), commit(), rollback() を使用して、トランザクションをコントロールします。


それぞれの方法について、簡単に、メリット・デメリットを以下の表にまとめてみました。

/ @Resource を利用した実装 ネィティブなコードによる実装
メリット 一行の簡単な記述で、誰でも実装できる。 自由度が高い
デメリット ・デプロイメントの直接資材となる HttpServlet 乃至は SessionBean のみに実装可能と言う制約がある。
・ HttpServlet に実装した場合、スレッドセーフな実装とはなくなる。(のかな?)
・コード量が増える
・ InitialContext は、メモリーコストがかかる為、 close() の実装漏れをすると、障害を発生させる可能性がある。
とまあこんな具合かな?と考えています。その他ご意見など、是非コメントください。

さてこれで、トランザクションの利用方法が分かりましたので、いよいよ実装です。執筆者は今回、実装に自由度が利く上記 "2" の方法を使用して行いました。
(今回は特に JPA 等は利用しないで作成しました。アプリケーションの作成には、 NetBeans 6.5 Beta を利用しています。)


大雑把なクラス構成としては、 HttpServlet クラス、トランザクションファクトリークラス、トランザクションクラス、データアクセスクラスの4要素でアプリケーションコンポーネントを構成しました。
サーブレットはトランザクションファクトリのトランザクション取得メソッドを呼び出しトランザクションの取得をします。上記トランザクションを取得するコードについては、トランザクションファクトリークラスに実装し、サーブレットに実装したコードは、以下のとおりです。


final Trannsaction tx = TransactionFactory.get Trannsaction();

取得したトランザクションオブジェクトを使用して、トランザクションを開始します。

tx.begin();

その後、データアクセスクラスインスタンスを生成して、各メソッドを呼び出します。
final BookListEntity bookListEntity = new BookListEntity("jdbc/xatorutuga");
final ShoppingCartEntity shoppingCartEntity = new ShoppingCartEntity("jdbc/xaportroyal");


bookListEntity.regist(・・・
shoppingCartEntity.regist(・・・
bookListEntity.findAll(・・・
shoppingCartEntity.findAll(・・・



前回のトピックに書いたとおり、二つのデータベースに配置した、それぞれのテーブルに対するデータアクセスクラスを作成しました。


データアクセスクラス側のコードはこうなります。(BookListEntity を例に揚げます。)
private final String datasourceName;

public BookList(final String datasourceName) {
this.datasourceName = datasourceName;
}

public final List<Object> findAll() throws NamingException, SQLException {
final Connection conn = this.getConnection();


conn.close();
}

public final int regist(final String isbn, final String bookTitle, final String author, final String yearOfPublication, final String publisher) throws NamingException, SQLException {
final Connection conn = this.getConnection();


conn.close();
}

private final Connection getConnection() throws NamingException, SQLException {
final Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
final Context ctx = new InitialContext(env);
final Connection conn = (Connection)ctx.lookup(this.datasourceName);
ctx.close();
}


※今更言うことでもないですが、ここで特筆すべきは、前回のトピック冒頭に記載したとおり、データアクセス都度コネクションプールからコネクションオブジェクトを取り出し、処理終了時にコネクションプールへ返却すると言う実装になり、コネクション数の節約が可能になることです。

そして再びサーブレットへ戻り、トランザクションを終了します。

tx.commit();


と大雑把にここまで、 JTA を利用した場合の実装方法を執筆してまいりましたが、如何でしたでしょうか?
方法論さえしっかりと押さえてしまえば、だれでも簡単にこの JTA を利用することが、 GlassFish 上で実現できます。


今回検証用に作成したサンプルアプリケーションは、こちらからダウンロードできます。
※Note : 本アプリケーションで使用しているパッケージの "jp.glassfish" は、執筆者が日本 GlassFish ユーザ会(通称グラジェー)の、メーリングリストメンバーであることから使用させて頂いています。当リソースは、日本 GlassFish ユーザ会から配布された資産ではないものと、ご理解ください。


ソースコードは以下のコマンドでアーカイブを展開してください。

jar -xvf jacksparrow.war

展開された、WEB-INF ディレクトリ配下にある、 "src/java" ディレクトリ配下に格納されています。
JavaDoc は同じく、WEB-INF ディレクトリ配下に、"docs" と言うディレクトリがあるので、そこに格納されています。
テーブルのクリエイト文についても、 WEB-INF ディレクトリ配下 の DDL ディレクトリ配下に格納されています。


最後に、今回検証用に作成しました、サンプルアプリケーションのクラス図と、シーケンス図を掲載いたします。

クラス図
xa-class-diagram.jpg


シーケンス図
xa-sequence-diagram.jpg


さて次回は、アプリケーションのデプロイ方法と、 HTTPRequest FORM Data のロケールについて、執筆して行きたいと思います。


簡単副業で収入アップ!

短期・日払い・高収入!稼げる情報満載♪

Comments

Pingback from jacksparrow » Java HttpServlet 初心忘れるべからず!
Date: 2008 年 10 月 6 日, 10:24 AM

[...] 前回は、 XA の使い方について執筆しました。今回は、基本に立ち戻って、今更ながら HttpServlet で扱うリクエストパラメータのエンコーディングの話を執筆したいと思います。 GlassFish [...]


Write a comment





*
画像に書かれた文字を入力してください

スパム対策用画像
ログインすると画像認証なしで投稿できます

ホットワード 利用 アプリケーション 実装 GlassFish
割引クーポンまとめ情報 - クー割