JCA 入門記 コネクション管理 その 1

ごめんなさい( -_-)
またサボってました…。
ちがうの、without EJB の翻訳してたの。
まぁ言い訳ですが。


っていうか,すっかり翻訳というか意訳の私訳の超約 (© money さん) にしてしまったのですが,そんなんでいいのだろうか?
あ,スレ違い (違) だ.


ともあれ (JW),新章突入です〜.


Chapter 6 Connection Management
この章では,アプリケーションサーバとリソースアダプタ間におけるコネクション管理について規定しているとのことです.


6.1 Overview
アプリケーションは,コネクションファクトリを使用してコネクションを取得し,EIS に接続します.リソースアダプタは,そのコネクションのファクトリとして振る舞うとのことです.
コネクションの接続や切断が高くつく場合は,コネクションプーリングが使われることが一般的です.コネクション管理規約はコネクションプーリングをサポートするそうです.


6.2 Goals
コネクション管理における規約の目標は次の通り.

  • 管理されたアプリケーション (Web コンテナや EJB コンテナ上のコンポーネント) でも,管理されないアプリケーション (2 層 C/S のクライアント) でも,一貫したプログラミングモデルでコネクションを取得できるようにする.
  • リソースアダプタが,EIS 固有のコネクションファクトリおよびコネクションインタフェースを CCI をベースとして提供することが出来るようにすること.既存の JDBC ドライバをJCA 対応にするためのインパクトを最小限にすること.
  • アプリケーションサーバがリソースアダプタに様々なサービス (トランザクション,セキュリティ,高度なプーリング,エラートラッキングやロギング) を提供するための汎用的なメカニズムを提供すること.
  • コネクションプーリングのサポートを提供すること.

最後のはその前と重複しているような気のせいがしますが,特に重要な目標であるらしく,さらに詳細に解説されていたりします.なんでも,効果的で,スケーラブルで,拡張可能なコネクションプーリングを可能とするようなメカニズムを提供するんだとかなんだとか.でもでも,特定のメカニズムや実装を提供するんじゃないぞ,とのこと.
それから,コネクションを提供するのはリソースアダプタですが,コネクションプーリングを提供するのはアプリケーションサーバの役割ということになっているようです.


6.3 Architecutre: Connection Management
ここでは,アプリケーションサーバとリソースアダプタ間のアーキテクチャに関して仕様化された規約を見ていきます.


6.3.1 Overview: Managed Application Senario
まずですね,リソースアダプタはコネクションファクトリとコネクションを提供するそうです.ちなみにこのコネクションファクトリは既出の ManagedConnectionFactory とは異なります.ガビ〜ン (王).
コネクションファクトリとコネクションは,唯一の interface が決められているわけではなく,必要に応じて定義してもいいみたいです.
とはいえ,標準的なものも用意されていて,その一つがおなじみの

  • javax.sql.DataSource
  • java.sql.Connection

です.
ということはおそらく

  • javax.jms.ConnectionFactory
  • javax.jms.Connection

もその一つか.もしかしたら javax.jms.Session かもしれないけれど.
これらとは別に,JCA (CCI) でも次の interface が決められています.

  • javax.resource.cci.ConnectionFactory
  • javax.resource.cci.Connection

EIS のカテゴリに応じて,これら interface のいずれかを使うのが望ましいはずですが,独自の interface を提供しても良さそうというのがポイントかな.
そんなわけで,コネクションファクトリおよびコネクションはリソースアダプタが提供します.アプリケーションサーバはどんなコネクションファクトリが必要になるか分からないのだ.


アプリケーションは,JNDI からコネクションファクトリをルックアップして,そこから EIS へのコネクションを取得します.
その時,コネクションファクトリはアプリケーションサーバが提供する

  • javax.resource.spi.ConnectionManager

という interface の実装に処理を委譲しなければならないそうです.なんかおもしろい作りですね.本来ならコネクションファクトリはアプリケーションサーバが提供する形にしたかったのでしょうが,すでに JDBC や JMS などが個別のコネクションファクトリを定義していたのでこんな作りになっちゃったのだと思われます.


ともあれ (JW) ConnectionManager ですが,こいつは Quality of Services を提供するのだとか.その QoS には例によって例のごとくトランザクション管理やセキュリティ,コネクションプールなどが含まれます.
そんなわけで (どんなわけで?),リソースアダプタが提供するコネクションファクトリは ConnectionManager

    • Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cxRequestInfo)

を呼び出して,コネクションの作成を依頼します.
アプリケーションサーバが提供する ConnectionManager の実装クラスは,コネクションプールに使えるコネクションがあればそれを返し,なければリソースアダプタが提供する (おなじみの)

  • javax.resource.spi.ManagedConnectionFactory

から新しい物理コネクションを取得します.なんか行ったり来たりですね...


アプリケーションサーバは,ManagedConnectionFactory に対して,

  • javax.resource.spi.ConnectionEventListener

を登録します.これにより,アプリケーションサーバは物理コネクションからのイベント (エラーになったとかトランザクションロールバックしちゃったとか) を受け取ることが出来るようになります.


ともあれ (JW),アプリケーションサーバManagedConnectionFactory から新しい物理コネクションを作成してもら訳ですが,そのために呼び出すのが

    • ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cxRequestInfo)

です.
第二引数の ConnectionRequestInfo は元々はリソースアダプタから ConnectionManager#allocateConnection(ManagedConnectionFactory, ConnectionRequestInfo) に渡されたものでしょうね.
戻り値となっている

  • javax.resource.spi.ManagedConnection

という interface ですが,こいつが EIS への物理コネクションであり,プーリングの対象となります.


ManagedConnection はあくまでも物理的なコネクションを表現するものなので,そのままアプリケーションに返すわけにはいきません.close() とか呼ばれると困っちゃうので.
そんなわけで (どんなわけで?),ManagedConnection はアプリケーションが使う論理コネクション (JCA 用語では「ハンドル」) を返してくれるメソッドを持っています.それが

    • Object getConnection(Subject subject, ConnectionRequestInfo cxRequestInfo)

です.
戻り値が Object なのは,java.sql.Connectionjavax.jms.Connection (もしかしたら javax.jms.Session),javax.resource.cci.Connection を実装したクラスあるいはリソースアダプタ独自のコネクションクラスになり得るからでしょう.
そんなわけで (どんなわけで?),ConnectionManager はこの論理コネクション (ハンドル) をコネクションファクトリに返します.
コネクションファクトリはそれをアプリケーションに返します.これでようやく EIS に対する操作が行えるようになるということですね.ふ〜っ,長っ!


ともあれ (JW),
アプリケーション ←→ リソースアダプタ ←→ アプリケーションサーバ ←→ リソースアダプタ
という旅をするようです.


リソースアダプタは分散トランザクションをサポートすることが出来ます.その場合は,

  • javax.transaction.xa.XAResource

の実装を提供します.
分散トランザクションではなく,ローカルトランザクションをサポートすることも出来て,その場合は

  • javax.resource.spi.LocalTransaction

の実装を提供します.
アプリケーションサーバはこれらを ManagedConnection から次のメソッドでこれらを取得します.

    • XAResource getXAResource()
    • LocalTransaction getLocalTransaction()

が,トランザクションに関して詳しくは 7 章まで待て.らじゃ.


ということで今日はここまで.ようやく JCA を学習している気分になってきました♪


ところで,EJB 同様に JCA もまた J2EE の様々な API の上に成り立っているようです.
例えば javax.resource.cci.ConnectionFactoryjavax.resource.Referenceableextends しているのですが,それは JNDI の javax.naming.Referenceableextends しています.
また,ManagedConnectionFactorycreateManagedConnection(Subject, ConnectionRequestInfo) の第一引数に出てくる Subject は JAAS のものです.
うーみゅ,S2JCA の道は険しいかも?