Tomcat 5.5.* 系での DataSource ( データソース ) の利用 - server.xml 編-
技術情報 TOP へ

本ページでの使用環境
OS:Windows XP SP 2 ( Linux 系 OS の場合も本ページと手順は同様です。 )
Java:JDK 5.0 UPDATE 8
Tomcat:5.5.20

Tomcat 5.5.* 系の server.xml ファイルを修正してデータソースを作成し、簡単なプログラムから利用してみます。

ここでは、JDK 5.0 UPDATE 8 、Tocmat 5.5.20 がインストールされていることを前提として説明いたします。 これらのインストールについては下記のページを参照ください。

JDK のインストール -Windows 編-

Tomcat 5.5.* 系のインストール - Windows 編 ( exe , zip ファイル ) -
* ここでは zip ファイルを使用して C:\apache-tomcat-5.5.20 に Tomcat をインストールした前提とします。
CATALINA_HOME は、C:\apache-tomcat-5.5.20 です。
( exe ファイルを使用してインストールした場合も本ページの手順で作成可能です。 )

データソースを利用する対象の Web アプリケーションがすでに存在し、利用可能である前提で説明しますので、 まだ Web アプリケーションを作成していない場合は、
以下のページを参考にデータソースを利用する対象の Web アプリケーションを作成してください。

Eclipce を使用した簡単な Java サーブレットの作成

ここでは、データソースを利用する対象の Web アプリケーションのコンテキストパスを「/HelloWebApp」 とします。


以下、Tomcat の server.xml を使用してデータソース ( コネクションプール ) を作成し、簡単なプログラムから利用してみます。




( 1 ) server.xml の修正

修正対象ファイル:
CATALINA_HOME/conf/server.xml

既にコンテキストパス 「/HelloWebApp」としたWeb アプリケーションが動作する環境が作成されている
ことを前提としますので CATALINA_HOME/conf/server.xml には HelloWebApp の
Context 要素が存在すると思います。

デフォルトでは server.xml の Context 要素は以下のような記述になっています。

* C:/workspace/HelloWebApp を docBase とします。

〜略〜
<Context path="/HelloWebApp" reloadable="true" docBase="C:/workspace/HelloWebApp" 
workDir="C:/workspace/HelloWebApp/work" />
</Host>
</Engine>


上記のファイル内容を以下のように修正します。

〜略〜
        <Context
            docBase="C:/workspace/HelloWebApp"
            path="/HelloWebApp"
            reloadable="true"
            workDir="C:/workspace/HelloWebApp/work">
          <Resource
            name="jdbc/oracle"
            type="javax.sql.DataSource"
            username="scott"
            password="tiger"
            driverClassName="oracle.jdbc.driver.OracleDriver"            
            url="jdbc:oracle:thin:@192.168.0.123:1521:sid"
            maxIdle="5"
            maxWait="5000"
            initialSize="5"
            maxActive="5"/>
        </Context>
      </Host>
    </Engine>
上記の設定では、データソース作成時に 5 つの ESTABLISHED ( 確立された DB との接続 ) が作成保持されます。

各パラメータについて簡単に説明します。

initialSize:
初期処理時に作成される接続の数

maxIdle:
未使用の接続を保持する最大数

maxActive
使用されるアクティブな接続を保持する最大数

maxWait
接続待ちの最大時間

----------------
例 1: initialSize=20 、maxIdle=20 の場合
初期処理時に initialSize の値 20 の接続が作成され、その接続が未使用で
あっても maxIdle の値 20 の接続が保持されます。

netstat コマンドで確認すると ESTABLISHED が 20 となります。
----------------
例 2: initialSize=20 、maxIdle=10 の場合
初期処理時に initialSize の値 20 の接続が作成され、その接続が未使用で
あっても maxIdle の値 10 の接続が保持されます。残りの 10 については
破棄されます。

netstat で確認すると ESTABLISHED が 10 、TIME_WAIT が 10 となります。
( 10 破棄されるので TIME_WAIT が 10 となります。 )


* 但し、初期処理時に DBCP の BasicDataSource によるデータベースへの接続
確認、切断処理 ( 疎通確認処理 ) が行われますので、TIME_WAIT ( 切断された接続 ) が 1 残ります。

その他のパラメータや詳細については以下のページを参照してください。

commons DBCP
- Parameters
http://jakarta.apache.org/commons/dbcp/configuration.html



( 2 ) データソース利用プログラムの作成

HelloWebApp 内でデータソースを利用するプログラムの作成を行います。

SimpleServlet.java
package hello;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.sql.DataSource;

public class SimpleServlet extends HttpServlet {
	
	protected DataSource baseDataSource = null;
	
	protected String jndiName = "java:comp/env/jdbc/oracle";
	//protected String jndiName = "java:comp/env/jdbc/postgres";

	
	public void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
                throws ServletException, IOException {
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null; 
		String rec = null;
		
		try {
		    
		    /* Connectionの取得 */
		    conn = baseDataSource.getConnection();
		    
		    /* Statementの作成 */
		    stmt = conn.createStatement();

		    /* SQL の実行、Resultsetの取得 */
		    rset = stmt.executeQuery("select EMPNO from EMP");
		    
		    response.setContentType("text/html; charset=Shift_JIS");

		    /* HTML 出力用 PrintWriter */
		    PrintWriter out = response.getWriter();
		    
		    /* HTML出力 */
		    out.println("<html>");
		    out.println("<head>");
		    out.println("<title>Data Source</title>");
		    out.println("</head>"); 
		    out.println("<body>");
		    out.println("select EMPNO from EMP<BR>");
		    out.println("<font size=\"2\">");
		    /* 取得したデータを表示します。 */
		    while (rset.next()) {
		    	out.println(rset.getString(1));	
		    	out.println("<BR>");
		    }
		    out.println("</font>");
		    
		    out.println("</body>");
		    out.println("</html>");
		    out.close();
		    
		    
		} catch (Exception e) {	
		    e.printStackTrace();
		}finally{		    
		try {
		    /* クローズ処理 */
		    if(conn != null){
		      conn.close();
		      conn = null;
		    }
		    if(stmt != null){
		      stmt.close();	
		      stmt = null;
		    }		    
		    if(rset != null){
		      rset.close();
		      rset = null;
		    }
		} catch (SQLException e) {		    
		    e.printStackTrace();
		}
	 }	
	}	
	public void init() throws ServletException {
		super.init();
		try {			 
		      getDataSource();
		    } catch (NamingException e) {
		      e.printStackTrace();
		}	
	}	
	
	private synchronized void getDataSource() throws NamingException{
		if (baseDataSource == null) {
		      Context initialContext = new InitialContext();
		      baseDataSource = (DataSource) initialContext.lookup(jndiName);
		}
	}
}
上記のプログラムの簡単な説明
ここでは、データソースの取得に init メソッドを利用します。

init メソッドとは、対象のサーブレットが呼び出された時 ( 実行時 ) に一度だけ実行されます。 
初期化処理などによく利用されるメソッドです。

データソースの取得には比較的処理時間がかかるため、init メソッドなどの初期化処理で
一度だけ行うようにします。

データソースの取得は、以下のプログラムで行います。

Context initialContext = new InitialContext();
baseDataSource = (DataSource) initialContext.lookup(jndiName);

init メソッド実行時にインスタンス変数 baseDataSource に対して initialContext.lookup(jndiName) 
で取得した DataSource  を代入するメソッドを呼び出しています。

インスタンス変数 baseDataSource は他のスレッド ( リクエスト ) からも利用されます。

インスタンス変数やクラス変数に代入しておければオブジェクトは保持されるため、
再度 DataSource を取得する必要はなく、DataSource は再利用可能となります。
( 但し、インスタンス変数やクラス変数はスレッドアンセーフです。代入処理には注意が必要で、
ここでは、念のため synchronized を使用しています。 )

但し、上記のプログラムはあくまで DataSource を取得するサンプルとなります。

実際にシステム開発などで DataSource を利用する場合は、別の DataSource 取得、保持クラスを
作成したり、それらを行う親クラスなどを作成し、サブクラスから利用するなどが一般的です。

		



( 3 ) ビルドとデプロイ

上述 ( 2 ) のプログラムをビルド、デプロイします。



( 4 ) JDBC ドライバの配置

JDBC ドライバを CATALINA_HOME/common/lib/ に配置します。





( 5 ) Tomcat の再起動

Tomcat の再起動を行います。



( 6 ) コネクションの確認

netstat コマンド等でコネクションの確認を行います。

例:
# netstat -na| findstr 1521



上述のパラメータの値を使用した設定では、ESTABLISHED ( 確立された DB との接続 ) が 5 つとなるはずです。 上記の netstat の結果を見ると ESTABLISHED の数は 5 つですので正常に接続が設立されています。

TIME_WAIT ( 切断された接続 ) が 1 つありますが、これは上述したように 初期処理時に DBCP の BasicDataSource によるデータベースへの接続確認、切断処理 ( 疎通確認処理 ) が 行われたために残った TIME_WAIT です。この結果で意図どおりのデータソースが作成されていると言えます。

5 つのコネクションプールができました。このコネクションプールを利用してみましょう。



( 6 ) 動作確認

下記のアドレスにブラウザでアクセスします。
< http://localhost:8080/HelloWebApp/SimpleServlet >

以下の画面が表示されれば成功です。





技術情報 TOP へ


Google
WWW を検索 whitemark.co.jp を検索

Copyright © 2006 by WhiteMark, All rights Reserved. Last Modified: 2006/05