The Ja-Jakarta ProjectTomcat Servlet/JSP コンテナ

リンク

ユーザガイド

リファレンス

Tomcat開発

Tomcat5 サーブレット/JSP コンテナ

JNDIデータソースの手引き

Printer Friendly Version
印刷用
バージョン
Table of Contents
目次

はじめに
データベース接続プール(DBCP)の設定
Tyrex接続プール
DBCP以外のソリューション
OCIクライアントを使用したOracle 8i
一般的な問題

Introduction
はじめに

JNDI Datasource configuration is covered extensively in the JNDI-Resources-HOWTO however, feedback from tomcat-user has shown that specifics for individual configurations can be rather tricky.

JNDIデータソースの設定はJNDIリソースの手引きでおおまかな説明をしていますが、 個々の設定項目への指定は少々特殊であるという、 tomcat-userからのフィードバックがありました。

Here then are some example configurations that have been posted to tomcat-user for popular databases and some general tips for db useage.

ここにあるのは、tomcat-userメーリングリストに投稿された主要なデータベース用のいくつかの設定例とデータベースを扱うための一般的なヒントです。

You should be aware that since these notes are derived from configuration and/or feedback posted to tomcat-user YMMV :-). Please let us know if you have any other tested configurations that you feel may be of use to the wider audience, or if you feel we can improve this section in anyway.

これらの情報は、tomcat-userメーリングリストへ投稿された設定やフィードバックに由来しています。 より多くの人々が使えるかも知れないと思うテスト済みの他の設定がある場合や、 何らかによりこのセクションを改善できると思った場合は、それをレポートしてください。

Database Connection Pool (DBCP) Configurations
データベース接続プール(DBCP)の設定

DBCP provides support for JDBC 2.0. On systems using a 1.4 JVM DBCP will support JDBC 3.0. Please let us know if you have used DBCP and its JDBC 3.0 features with a 1.4 JVM.

DBCPはJDBC2.0をサポートします。システムが1.4JVMを使っている場合はDBCPはJDBC3.0をサポートします。 もしDBCPとJDBC3.0の機能を1.4JVMで使っている場合は知らせてください。

See the DBCP Javadocs BasicDataSource class for a complete list of configuration parameters.

設定パラメータの完全な一覧は DBCP JavadocsのBasicDataSourceクラスを参照してください。

[訳者コメント: DBCP Javadocs のリンク先を http://jakarta.apache.org/commons/dbcp/apidocs/index.html に変更。 ]

インストール

DBCP uses the Jakarta-Commons Database Connection Pool. It relies on number of Jakarta-Commons componenets:
DBCP はJakarta-Commons Database Connection Poolを使います。 これはいくつかのJakarta-Commonsコンポーネントに依存します。:
  • Jakarta-Commons DBCP 1.0
  • Jakarta-Commons Collections 2.0
  • Jakarta-Commons Pool 1.0
These jar files along with your the jar file for your JDBC driver should be installed in $CATALINA_HOME/common/lib.
これらのjarファイルはJDBCドライバと一緒に $CATALINA_HOME/common/libにインストールします。
NOTE:Third Party drivers should be in jarfiles, not zipfiles. Tomcat only adds $CATALINA_HOME/common/lib/*.jar to the classpath.
注意:サードパーティ製のドライバはzipファイルではなく、jarファイルにしてください。 Tomcatは$CATALINA_HOME/common/lib/*.jarのみをクラスパスに追加します。
NOTE: Do not install these jarfiles in your /WEB-INF/lib, or $JAVA_HOME/jre/lib/ext, or anywhere else. You will experience problems if you install them anyplace other than $CATALINA_HOME/common/lib.
注意: これらのjarファイルを/WEB-INF/lib$JAVA_HOME/jre/lib/ext、 その他の場所にインストールしないでください。 $CATALINA_HOME/common/lib以外の場所にインストールすると問題が発生するでしょう。

データベース接続プールのリーク予防策

A database connection pool creates and manages a pool of connections to a database. Recycling and reusing already existing connections to a dB is more efficient than opening a new connection.

データベース接続プールは、データベースへの接続のプールを生成・管理します。 既存のデータベースへの接続を再生し再利用することは、新規に接続を開くよりもさらに効率的です。

There is one problem with connection pooling. A web application has to explicetely close ResultSet's, Statement's, and Connection's. Failure of a web application to close these resources can result in them never being available again for reuse, a db connection pool "leak". This can eventually result in your web application db connections failing if there are no more available connections.

接続のプーリングには一つ問題があります。WebアプリケーションはResultSet、 Statement、およびConnectionを明示的に閉じなければなりません。 Webアプリケーションがこれらのリソースを閉じていないと、データベース接続の"リーク"となり、 再利用不可能という結果になります。 有効な接続が無くなると、ついにはWebアプリケーションのデータベース接続失敗という結果になります。

There is a solution to this problem. The Jakarta-Commons DBCP can be configured to track and recover these abandoned dB connections. Not only can it recover them, but also generate a stack trace for the code which opened these resources and never closed them.

この問題には解決策があります。Jakarta-Commons DBCPはこれらの放棄されたデータベース接続を追跡し、 回復するように設定できます。 しかも接続を回復するだけでなく、これらのリソースを開始し閉じなかったコードのスタックトレースを生成できます。

To configure a DBCP DataSource so that abandoned dB connections are removed and recycled add the following paramater to the ResourceParams configuration for your DBCP DataSource Resource:
            <parameter>
              <name>removeAbandoned</name>
              <value>true</value>
            </parameter>
When available db connections run low DBCP will recover and recyle any abandoned dB connections it finds. The default is false.

放棄されたデータベース接続を解放し、再生するようにDBCPデータソースを設定するには、 次のparamaterをDBCPデータソースのResourceにあるResourceParamsの設定に追加します。:

            <parameter>
              <name>removeAbandoned</name>
              <value>true</value>
            </parameter>
有効なデータベース接続が動作する場合、低レベルのDBCPは見つかったすべての放棄されたデータベース接続を回復し再生します。 デフォルトはfalseです。

Use the removeAbandonedTimeout parameter to set the number of seconds a dB connection has been idle before it is considered abandoned.
            <parameter>
              <name>removeAbandonedTimeout</name>
              <value>60</value>
            </parameter>
The default timeout for removing abandoned connections is 300 seconds.

データベース接続が放棄されたと見なすまでのアイドル秒数を設定するには、 removeAbandonedTimeoutパラメータを使います。

            <parameter>
              <name>removeAbandonedTimeout</name>
              <value>60</value>
            </parameter>
接続が放棄され、解放されるまでのデフォルトタイムアウトは300秒です。

The logAbandoned parameter can be set to true if you want DBCP to log a stack trace of the code which abandoned the dB connection resources.
            <parameter>
              <name>logAbandoned</name>
              <value>true</value>
            </parameter>
The default is false.

データベース接続リソースが放棄されたコードのスタックトレースをDBCPにログ採取させたい場合は、 logAbandonedパラメータをtrueに設定します。

            <parameter>
              <name>logAbandoned</name>
              <value>true</value>
            </parameter>
デフォルトはfalseです。

MySQLのDBCP設定例

0. Introduction

0. はじめに

Versions of MySQL and the mm.mysql JDBC driver when have been reported to work:
  • MySQL 3.23.47, MySQL 3.23.47 using InnoDB, MySQL 4.0.1alpha
  • mm.mysql 2.0.14 (JDBC Driver)
Please let us know if you have tested the new MySQL mm.mysql 3.0 driver.

動作が報告されているMySQLのバージョンとmm.mysql JDBCドライバ:

  • MySQL 3.23.47、InnoDBを使用したMySQL 3.23.47、MySQL 4.0.1alpha
  • mm.mysql 2.0.14 (JDBCドライバ)
新しいMySQL mm.mysql 3.0ドライバをテストした場合は、その結果をレポートしてください。

1. MySQL configuration

1. MySQLの設定

Ensure that you follow these instructions as variations can cause problems.

他のやり方では問題の原因になることがあるので、次の手順を確実に行ってください。

Create a new test user, a new database and a single test table. Your MySQL user must have a password assigned. The driver will fail if you try to connect with an empty password.
mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost 
    ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION;
mysql> create database javatest;
mysql> use javatest;
mysql> create table testdata (
    ->   id int not null auto_increment primary key,
    ->   foo varchar(25), 
    ->   bar int);
Note: the above user should be removed once testing is complete!

新しいテスト用ユーザ、新しいデータベースおよび単一のテスト用テーブルを作成します。 MySQLユーザには必ずパスワードを割り当てなければなりません。 ドライバが空のパスワードで接続しようとすると失敗します。

mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost 
    ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION;
mysql> create database javatest;
mysql> use javatest;
mysql> create table testdata (
    ->   id int not null auto_increment primary key,
    ->   foo varchar(25), 
    ->   bar int);
注意:一度テストが成功したら上記のユーザは削除しましょう。

Next insert some test data into the testdata table.
mysql> insert into testdata values(null, 'hello', 12345);
Query OK, 1 row affected (0.00 sec)

mysql> select * from testdata;
+----+-------+-------+
| ID | FOO   | BAR   |
+----+-------+-------+
|  1 | hello | 12345 |
+----+-------+-------+
1 row in set (0.00 sec)

mysql>

次に、テストデータ用のテーブルにテストデータを入れます。

mysql> insert into testdata values(null, 'hello', 12345);
Query OK, 1 row affected (0.00 sec)

mysql> select * from testdata;
+----+-------+-------+
| ID | FOO   | BAR   |
+----+-------+-------+
|  1 | hello | 12345 |
+----+-------+-------+
1 row in set (0.00 sec)

mysql>

2. server.xml configuration

2. server.xmlの設定

Configure the JNDI DataSource in Tomcat by adding a declaration for your resource to $CATALINA_HOME/conf/server.xml.

TomcatのJNDIデータソースの設定を行うには$CATALINA_HOME/conf/server.xml にリソースの宣言を追加します。

Add this in between the </Context> tag of the examples context and the </Host> tag closing the localhost definition.
<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">

  <Logger className="org.apache.catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." suffix=".txt"
             timestamp="true"/>

  <Resource name="jdbc/TestDB"
               auth="Container"
               type="javax.sql.DataSource"/>

  <ResourceParams name="jdbc/TestDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>

    <!-- Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to 0 for no limit.
         -->
    <parameter>
      <name>maxActive</name>
      <value>100</value>
    </parameter>

    <!-- Maximum number of idle dB connections to retain in pool.
         Set to 0 for no limit.
         -->
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>

    <!-- Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>

    <!-- MySQL dB username and password for dB connections  -->
    <parameter>
     <name>username</name>
     <value>javauser</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value>javadude</value>
    </parameter>

    <!-- Class name for mm.mysql JDBC driver -->
    <parameter>
       <name>driverClassName</name>
       <value>org.gjt.mm.mysql.Driver</value>
    </parameter>

    <!-- The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         -->
    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value>
    </parameter>
  </ResourceParams>
</Context>

この記述をexamplesコンテキストの</Context>タグの間に追加し、 </Host>タグでlocalhost定義を閉じます。

<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">

  <Logger className="org.apache.catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." suffix=".txt"
             timestamp="true"/>

  <Resource name="jdbc/TestDB"
               auth="Container"
               type="javax.sql.DataSource"/>

  <ResourceParams name="jdbc/TestDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>

    <!-- プール内のデータベース接続の最大数。 mysqld max_connectionsが
         すべてのデータベース接続を処理するのに充分な大きさに設定されていることを
         確認すること。0を設定すると無制限になる。
         -->
    <parameter>
      <name>maxActive</name>
      <value>100</value>
    </parameter>

    <!-- アイドルとしてプール内に残すデータベース接続の最大数。
         0を設定すると無制限になる。
         -->
    <parameter>
      <name>maxIdle</name>
      <value>30</value>
    </parameter>

    <!-- データベース接続が利用可能になるまでの最大待ち時間(ミリ秒単位)
         この設定例は10秒。このタイムアウトを超過すると例外が投げられる。
         -1を設定すると無限に待つ。
         -->
    <parameter>
      <name>maxWait</name>
      <value>10000</value>
    </parameter>

    <!-- データベース接続用のMySQLデータベースユーザ名とパスワード -->
    <parameter>
     <name>username</name>
     <value>javauser</value>
    </parameter>
    <parameter>
     <name>password</name>
     <value>javadude</value>
    </parameter>

    <!-- mm.mysql JDBCドライバクラス名 -->
    <parameter>
       <name>driverClassName</name>
       <value>org.gjt.mm.mysql.Driver</value>
    </parameter>

    <!-- MySQLデータベースへ接続するためのJDBC接続URL。
         URLの引数 autoReconnect=true はmysqldが接続と閉じた場合に
         mm.mysql JDBCドライバが自動的に再接続することを保証する。
         デフォルトではmysqldは8時間後にアイドル状態となった接続を閉じる。
         -->
    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/javatest?autoReconnect=true</value>
    </parameter>
  </ResourceParams>
</Context>

3. web.xml configuration

3. web.xmlの設定

Now create a WEB-INF/web.xml for this test application.
<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

テストアプリケーションにWEB-INF/web.xmlを作成します。

<?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

4. Test code

4. テスト用コード

Now create a simple test.jsp for use later.
<html>
  <head>
    <title>DB Test</title>
  </head>
  <body>

  <%
    foo.DBTest tst = new foo.DBTest();
    tst.init();
  %>

  <h2>Results</h2>
    Foo <%= tst.getFoo() %><br/>
    Bar <%= tst.getBar() %>

  </body>
</html>

後で使うために、簡単なsimple.jspを作成します。

<html>
  <head>
    <title>DB Test</title>
  </head>
  <body>

  <%
    foo.DBTest tst = new foo.DBTest();
    tst.init();
  %>

  <h2>Results</h2>
    Foo <%= tst.getFoo() %><br/>
    Bar <%= tst.getBar() %>

  </body>
</html>

And create a Java class to actually use your new Datasource and connection pool. Note: this code isn't anywhere near production ready - it's only supposed to be used as a simple test :-)
package foo;

import javax.naming.*;
import javax.sql.*;
import java.sql.*;

public class DBTest {

  String foo = "Not Connected";
  int bar = -1;
    
  public void init() {
    try{
      Context ctx = new InitialContext();
      if(ctx == null ) 
          throw new Exception("Boom - No Context");

      DataSource ds = 
            (DataSource)ctx.lookup(
               "java:comp/env/jdbc/TestDB");

      if (ds != null) {
        Connection conn = ds.getConnection();
              
        if(conn != null)  {
            foo = "Got Connection "+conn.toString();
            Statement stmt = conn.createStatement();
            ResultSet rst = 
                stmt.executeQuery(
                  "select id, foo, bar from testdata");
            if(rst.next()) {
               foo=rst.getString(2);
               bar=rst.getInt(3);
            }
            conn.close();
        }
      }
    }catch(Exception e) {
      e.printStackTrace();
    }
 }

 public String getFoo() { return foo; }
 public int getBar() { return bar;}
}

また、実際に新しいデータソースと接続プールを使うJavaクラスを作成します。 注意: このコードは製品として実用できるだけの品質を確保していません。簡単なテストのみに使えます。

package foo;

import javax.naming.*;
import javax.sql.*;
import java.sql.*;

public class DBTest {

  String foo = "Not Connected";
  int bar = -1;
    
  public void init() {
    try{
      Context ctx = new InitialContext();
      if(ctx == null ) 
          throw new Exception("Boom - No Context");

      DataSource ds = 
            (DataSource)ctx.lookup(
               "java:comp/env/jdbc/TestDB");

      if (ds != null) {
        Connection conn = ds.getConnection();
              
        if(conn != null)  {
            foo = "Got Connection "+conn.toString();
            Statement stmt = conn.createStatement();
            ResultSet rst = 
                stmt.executeQuery(
                  "select id, foo, bar from testdata");
            if(rst.next()) {
               foo=rst.getString(2);
               bar=rst.getInt(3);
            }
            conn.close();
        }
      }
    }catch(Exception e) {
      e.printStackTrace();
    }
 }

 public String getFoo() { return foo; }
 public int getBar() { return bar;}
}

Finally deploy your web app into $CATALINA_HOME/webapps either as a warfile called DBTest.war or into a sub-directory called DBTest

最後に、DBTest.warというwarファイルとして、 またはDBTestという名前のサブディレクトリとして $CATALINA_HOME/webappsにWebアプリケーションを配備します。

Once deployed, point a browser at http://localhost:8080/DBTest/test.jsp to view the fruits of your hard work.

配備したら、苦労した成果を見るために、ブラウザで http://localhost:8080/DBTest/test.jspを開きましょう。

Oracle 8i

0. Introduction

0. はじめに

We would appreciate comments on this section as I'm not an Oracle DBA :-)

私たちはOracle DBAではないので、このセクションに関するコメントの提供者に感謝します。

Oracle requires minimal changes from the MySQL configuration except for the usual gotchas :-) Firstly by default, Tomcat will only use *.jar files installed in $CATALINA_HOME/common/lib therefore classes111.zip or classes12.zip will need to be renamed with a .jar extension. Since jarfiles are zipfiles, there is no need to unzip and jar these files - a simple rename will suffice. Also, you should be aware that some (early) versions of Tomcat 4.0 when used with JDK 1.4 will not load classes12.zip unless you unzip the file, remove the javax.sql.* class heirarchy and rejar.

Oracleでは通常わかっていること以外にも、MySQL用の設定からは少々の変更が必要です。 まず、デフォルトではTomcatは$CATALINA_HOME/common/libにインストールされている、 *.jarファイルのみを使うので、classes111.zipclasses12.zip は拡張子を.jarにリネームする必要があります。 jarファイルはzipファイルなので、解凍してこれらのファイルをjarにする必要はありません。単純にリネームするだけで充分です。 さらに知っておくべきことがあります。JDK1.4で使ってTomcat4.0の(早期)バージョンを動かす場合は、 classes12.zipを解凍し、javax.sql.*階層のクラスを削除して再度jar化しないと読み込まれません。

1. server.xml configuration

1. server.xmlの設定

In a similar manner to the mysql config above, you will need to define your Datasource in your server.xml file. Here we define a Datasource called myoracle using the thin driver to connect as user scott, password tiger to the schema called myschema in the sid called mysid. (Note: with the thin driver this sid is not the same as the tnsname)

上記のMySQLの設定と同様のやり方でserver.xmlファイルのデータソースの定義をする必要があります。 これは、ユーザscott、パスワードtigerで、mysidというsidにあるmyschemaというスキーマに接続する、 thinドライバを使ったmyoracleというデータソースの定義です。 (注意:thinドライバを使った場合はsidはtnsnameと同一ではありません。)

Use of the OCI driver should simply involve a changing thin to oci in the URL string.
<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/myoracle">
  <parameter>
    <name>factory</name>
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  </parameter>
  <parameter>
    <name>driverClassName</name>
    <value>oracle.jdbc.driver.OracleDriver</value>
  </parameter>
  <parameter>
    <name>url</name>
    <value>jdbc:oracle:thin:myschema@127.0.0.1:1521:mysid</value>
  </parameter>
  <parameter>
    <name>username</name>
    <value>scott</value>
  </parameter>
  <parameter>
    <name>password</name>
    <value>tiger</value>
  </parameter>
  <parameter>
    <name>maxActive</name>
    <value>20</value>
  </parameter>
  <parameter>
    <name>maxIdle</name>
    <value>10</value>
  </parameter>
  <parameter>
    <name>maxWait</name>
    <value>-1</value>
  </parameter>
</ResourceParams>

OCIドライバを使う場合は単純にURL文字列中のthinをociに変更するだけです。

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/myoracle">
  <parameter>
    <name>factory</name>
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  </parameter>
  <parameter>
    <name>driverClassName</name>
    <value>oracle.jdbc.driver.OracleDriver</value>
  </parameter>
  <parameter>
    <name>url</name>
    <value>jdbc:oracle:thin:myschema@127.0.0.1:1521:mysid</value>
  </parameter>
  <parameter>
    <name>username</name>
    <value>scott</value>
  </parameter>
  <parameter>
    <name>password</name>
    <value>tiger</value>
  </parameter>
  <parameter>
    <name>maxActive</name>
    <value>20</value>
  </parameter>
  <parameter>
    <name>maxIdle</name>
    <value>10</value>
  </parameter>
  <parameter>
    <name>maxWait</name>
    <value>-1</value>
  </parameter>
</ResourceParams>

2. web.xml configuration

2. web.xmlの設定

You should ensure that you respect the elemeent ordering defined by the DTD when you create you applications web.xml file.

アプリケーションのweb.xmlファイルを作成するときには、 DTDで定義された要素の順序に従っていることを確認してください。

<resource-ref>
 <description>Oracle Datasource example</description>
 <res-ref-name>jdbc/myoracle</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>

3. Code example

3. コードの例

You can use the same example application as above (asuming you create the required DB instance, tables etc.) replacing the Datasource code with something like

データソースのコードをこのように書き換えれば上記のサンプルアプリケーションと同じものが使えます。 (データベースインスタンス、テーブル等は作成したものと想定します。)

Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
//etc.
PostgreSQL

0. Introduction

0. はじめに

PostgreSQL is configured in a similar manner to Oracle. Again, highlighting the differences. These notes are untested as yet and we would appreciate feedback.

PostgreSQLはOracleと同様のやり方で設定できますが、完全に同等ではないことを改めて強調しておきます。 これらの点はまだテストされていないため、フィードバックを高く評価したいと思います。

1. server.xml configuration

1. server.xmlの設定

<Resource name="jdbc/postgres" auth="Container"
          type="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/postgres">
  <parameter>
    <name>factory</name>
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
  </parameter>
  <parameter>
    <name>driverClassName</name>
    <value>org.postgresql.Driver</value>
  </parameter>
  <parameter>
    <name>url</name>
    <value>jdbc:postgresql://127.0.0.1:5432/mydb</value>
  </parameter>
  <parameter>
    <name>username</name>
    <value>myuser</value>
  </parameter>
  <parameter>
    <name>password</name>
    <value>mypasswd</value>
  </parameter>
  <parameter>
    <name>maxActive</name>
    <value>20</value>
  </parameter>
  <parameter>
    <name>maxIdle</name>
    <value>10</value>
  </parameter>
  <parameter>
    <name>maxWait</name>
    <value>-1</value>
  </parameter>
</ResourceParams> 

2. web.xml configuration

2. web.xmlの設定

<resource-ref>
 <description>postgreSQL Datasource example</description>
 <res-ref-name>jdbc/mydb</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>
Tyrex Connection Pool
Tyrex接続プール
はじめに

Tomcat 5 provides transaction management and resource configuration support through the use of Tyrex 1.0. This allows the user to obtain JTA/JCA resources from the JNDI namespace, as well as the standard javax.transaction.UserTransaction.

Tomcat5はトランザクション管理とTyrex 1.0 を使ったリソース設定のサポートを提供します。 ユーザはJTA/JCAリソースをjavax.transaction.UserTransactionと同様にJNDI名前空間より取得できます。

[訳者コメント: Tyrexサイトのリンク先を http://tyrex.sourceforge.net/ に修正。 ]

必要なJARファイルのインストール

In order for a web application to use Tyrex, the webapp and Tomcat need to have access to the Tyrex jar, as well as the jars it requires. Here is a list of the required jars, and where to obtain them:

WebアプリケーションでTyrexを使うには、WebアプリケーションとTomcatがTyrex jarファイルおよびそれが必要とするjarファイルにアクセスする必要があります。 次は必要なjarファイルの一覧およびそれらを入手する場所です:

The following jars are included with Tyrex binary distribution, available at http://tyrex.exolab.org.
  • tyrex-1.0.jar
  • ots-jts_1.0.jar
  • jta_1.0.1.jar
  • xerces-J_1.4.0.jar
The following two jars are required as well:

次のjarファイルは http://tyrex.sourceforge.net/ から入手可能なTyrexバイナリ配布版に含まれています。

[訳者コメント: Tyrexサイトのリンク先を http://tyrex.sourceforge.net/ に修正。 ]
  • tyrex-1.0.jar
  • ots-jts_1.0.jar
  • jta_1.0.1.jar
  • xerces-J_1.4.0.jar
同様に、次の2つのjarファイルも必要です:

All six of these jar files need to be placed on $TOMCAT_HOME/common/lib so that both Tomcat and your web application will see them.

これらすべての6つのjarファイルはTomcatとWebアプリケーションの両方から見えるように$CATALINA_HOME/common/libに配置する必要があります。

[訳者コメント: $TOMCAT_HOME(誤) -> $CATALINA_HOME(正) ]

Tyrexの設定

The Tyrex documentation (http://tyrex.exolab.org) provides complete details on how to properly configure Tyrex. As an example, we will use the following Tyrex configuration, specified in Tyrex's domain configuration XML file:

Tyrexのドキュメント(http://tyrex.sourceforge.net/)はTyrexのプロパティの正しく詳細な設定方法を提供します。 例として、Tyrexのドメイン設定XMLファイルで指定された次のTyrex設定を使います。

[訳者コメント: Tyrexサイトのリンク先を http://tyrex.sourceforge.net/ に修正。 ]

<domain>
  <name>myDomain</name>
  <resources>
    <dataSource>
      <name>myDatasource</name>
      <jar>/home/david/mm.mysql-2.0.14-bin.jar</jar>
      <class>org.gjt.mm.mysql.jdbc2.optional.MysqlXaDataSource</class>
      <config>
        <user>david</user>
        <password>secret</password>
        <serverName>localhost</serverName>
        <port>3306</port>
        <database>daviddb</database>
      </config>
    </dataSource>
  </resources>
</domain>

A few things to note:
  • You need to specify the full pathname of the JAR file (for relative paths, Tyrex looks in the current working directory, this usually isn't what you want). You can also specify a URL.
  • Any elements nested inside the elements are passed as parameters to the datasource class, using standard setter methods.
  • More configuration options are available, as well as a better description of how to setup Tyrex, at http://tyrex.exolab.org/configuration.html

いくつかの注意点:

  • jarファイルはフルパスで指定する必要があります。 (相対パスでは、Tyrexはカレントディレクトリを参照します。通常は、そうしません。) URLを指定することもできます。
  • 要素内にネストした全ての要素はデータソースクラスに標準的なsetterメソッドを使ってパラメータとして渡されます。
  • これ以上の設定オプションは、Tyrexの設定方法のより詳細な説明と同様に、 http://tyrex.sourceforge.net/configuration.htmlにあります。
[訳者コメント: Tyrexサイトのリンク先を http://tyrex.sourceforge.net/configuration.html に修正。 ]

This XML config file needs to be placed where Tomcat's classloader can find it using getResource(). This means that the WEB-INF/classes directory under your webapp is a very good choice.

このXML設定ファイルはTomcatのクラスローダがgetResource()メソッドを使って見つけられる場所に配置する必要があります。 WebアプリケーションのWEB-INF/classesディレクトリはとても良い選択です。

Configuring Tomcat

Now that your Tyrex XML config file is in place and ready, you must enlist the Tyrex resources in the JNDI namespace. This is done through Tomcat's server.xml file. Two important parameters must be specified: the name of the domain config file (tyrexDomainConfig), and the name of the Tyrex domain that is to be used (tyrexDomainName). These need to be setup as Environment parameters, like so:

Tyrex XML設定ファイルを配置して用意できたら、JNDI名前空間にTyrexリソースを登録します。 これはTomcatのserver.xmlファイルを使って行います。 重要なパラメータを2つ設定する必要があります。ドメイン設定ファイル名(tyrexDomainConfig)と、 使用するTyrexドメイン名(tyrexDomainName)です。 これらは次のようにEnvironmentパラメータとして設定する必要があります:

<Environment name="tyrexDomainConfig" type="java.lang.String" value="domain-config.xml"/>
<Environment name="tyrexDomainName" type="java.lang.String" value="myDomain"/>

Now, you must configure the resource (under the <Context> element of your webapp):

また、リソースの設定を行う必要があります。(Webアプリケーションの<Context>要素中に行います。):

<Resource name="my-datasource" auth="Container" type="tyrex.resource.Resource"/>
<ResourceParams name="my-datasource">
  <parameter>
    <name>name</name>
    <value>myDataSource</value>
  </parameter>
</ResourceParams>

A couple of things to point out:
  • The type of resource should always be tyrex.resource.Resource, regardless of how you have Tyrex configured.
  • Only one ResourceParam parameter is needed, name -- the value should be set to the name of resource specified in the Tyrex config file.
  • Note the difference between a Tomcat/JNDI resource and a Tyrex resource (it can be confusing at first glance!)

いくつかの注意点:

  • どのようにTyrexを設定していても、リソースの型は常にtyrex.resource.Resourceです。
  • ResourceParamパラメータにはnameのみが必要です。 -- 値はTyrex設定ファイルで指定したリソース名を設定します。
  • Tomcat/JNDIリソースとTyrexリソースの違いに注意してください。(一見、混乱を招きます!)

アプリケーションのコーディング

Making use of your Tyrex resource should now be relatively simple. To obtain your datasource, simply use JNDI:

Tyrexリソースは比較的簡単に使えます。単純にJNDIを使うだけでデータソースを取得できます。

InitialContext initCtx = new InitialContext();
DataSource ds = (DataSource) initCtx.lookup("java:comp/env/my-datasource");
Connection conn = ds.getConnection();
...and so on.

Tyrex also provides a javax.transaction.UserTransaction, obtainable through JNDI at the standard location (java:comp/UserTransaction).

Tyrexは標準のロケーション(java:comp/UserTransaction)からJNDI経由で取得できる、 javax.transaction.UserTransactionも提供します。

Non DBCP Solutions
DBCP以外のソリューション

These solutions either utilise a single connection to the database (not recommended for anything other than testing!) or some other pooling technology.

これらのソリューションでは、データベースへの単一の接続(テスト以外は推奨しません)、または他のプーリング技術を利用します。

Oracle 8i with OCI client
OCIクライアントを使ったOracle 8i
はじめに

OCIクライアントを使ったJNDIデータソースの生成に厳密に取り組まないうちは、上記のOracleとDBCPのソリューションと組み合わせることができます。

In order to use OCI driver, you should have an Oracle client installed. You should have installed Oracle8i(8.1.7) client from cd, and download the suitable JDBC/OCI driver(Oracle8i 8.1.7.1 JDBC/OCI Driver) from otn.oracle.com.

OCIドライバを使うにはOracleクライアントのインストールが必要です。Oracle8i(8.1.7)クライアントをCDよりインストールし、 適切なJDBC/OCIドライバ(Oracle8i 8.1.7.1 JDBC/OCIドライバ)をotn.oracle.comからダウンロードします。

[訳注: 日本では Oracle Technology Network Japan ( http://otn.oracle.co.jp/ ) からダウンロードすることも可能です。 ]

After renaming classes12.zip file to classes12.jar for Tomcat, copy it into $CATALINA_HOME/common/lib. You may also have to remove the javax.sql.* classes from this file depending upon the version of Tomcat and JDK you are using.

classes12.zipファイルをTomcat用にclasses12.jarにリネームし、 $CATALINA_HOME/common/libにコピーします。 使用しているTomcatとJDKのバージョン次第で、このファイルからjavax.sql.*クラスを削除する必要があるかも知れません。

すべてをひとつにまとめる

Ensure that you have the ocijdbc8.dll or .so in your $PATH or LD_LIBRARY_PATH (possibly in $ORAHOME\bin) and also confirm that the native library can be loaded by a simple test program using System.loadLibrary("ocijdbc8");

$PATHまたはLD_LIBRARY_PATHocijdbc8.dllまたは.soがあること(おそらく$ORAHOME\binにあります)を確認してください。そして、System.loadLibrary("ocijdbc8");を使った簡単なテストプログラムでネイティブライブラリがロードできることも確認してください。

You should next create a simple test servlet or jsp that has these critical lines:

次に、この重要な行を含んだテスト用の簡単なServletまたはJSPを作成します:

DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
conn =
DriverManager.getConnection("jdbc:oracle:oci8:@database","username","password");

where database is of the form host:port:SID Now if you try to access the URL of your test servlet/jsp and what you get is a ServletException with a root cause of java.lang.UnsatisfiedLinkError:get_env_handle.

テスト用Servlet/JSPのURLにアクセスしようとして、 元の理由がjava.lang.UnsatisfiedLinkError:get_env_handleであるServletExceptionが発生した場合、 データベースはhost:port:SID形式です。

First, the UnsatisfiedLinkError indicates that you have
  • a mismatch between your JDBC classes file and your Oracle client version. The giveaway here is the message stating that a needed library file cannot be found. For example, you may be using a classes12.zip file from Oracle Version 8.1.6 with a Version 8.1.5 Oracle client. The classeXXXs.zip file and Oracle client software versions must match.
  • A $PATH, LD_LIBRARY_PATH problem.
  • It has been reported that ignoring the driver you have downloded from otn and using the classes12.zip file from the directory $ORAHOME\jdbc\lib will also work.

まず、UnsatisfiedLinkErrorは以下のことを示しています。

  • JDBCクラスファイルとOracleクライアントとのバージョンのミスマッチ。 手がかりは必要なライブラリファイルが見つからない、と述べているメッセージです。 例えば、Oracleバージョン8.1.6のclasses12.zipファイルとバージョン8.1.5のOracleクライアントを使っているかも知れません。 classeXXXs.zipファイルとOracleクライアントソフトウェアのバージョンはマッチしていなければなりません。
  • $PATHLD_LIBRARY_PATHの問題。
  • otnからダウンロードしたドライバは無視して、 $ORAHOME\jdbc\libディレクトリにあるclasses12.zipファイルを使うと動作するという報告があります。

Next you may experience the error ORA-06401 NETCMN: invalid driver designator

それから、ORA-06401 NETCMN: invalid driver designatorというエラーが発生するかも知れません。

The Oracle documentation says : "Cause: The login (connect) string contains an invalid driver designator. Action: Correct the string and re-submit." Change the database connect string (of the form host:port:SID) with this one: (description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))

Oracleのドキュメントには次のようにあります。「理由:ログイン(接続)文字列に無効なドライバ指定が含まれています。対処:文字列を修正し、再送信してください。」 データベース接続文字列(host:port:SID形式)をこのように修正してください: (description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))

Ed. Hmm, I don't think this is really needed if you sort out your TNSNames - but I'm not an Oracle DBA :-)

うーん、もしTNSNamesが解決しているのならこれが必要とは思いません。 - 私はOracle DBAではありませんが。

Common Problems
一般的な問題

Here are some common problems encountered with a web application which uses a database and tips for how to solve them.

ここにはデータベースを使うWebアプリケーションが行き当たる共通の問題と、 それを解決するためのヒントがあります。

データベース接続が断続的に失敗する

Tomcat runs within a JVM. The JVM periodically performs garbage collection (GC) to remove java objects which are no longer being used. When the JVM performs GC execution of code within Tomcat freezes. If the maximum time configured for establishment of a dB connection is less than the amount of time garbage collection took you can get a db conneciton failure.

TomcatはJVM上で実行しています。JVMはもう使われないJavaオブジェクトを消去するためにガーベジコレクション(GC)を定期的に実行します。 JVMがGCを実行するとき、Tomcat内のコードの実行はフリーズします。 データベース接続を確立するための最大時間がガーベジコレクションに要する時間より小さく設定されている場合、 データベース接続は失敗します。

To collect data on how long garbage collection is taking add the -verbose:gc argument to your CATALINA_OPTS environment variable when starting Tomcat. When verbose gc is enabled your $CATALINA_BASE/logs/catalina.out log file will include data for every garbage collection including how long it took.

ガーベジコレクションにどれぐらい時間がかかるのかをデータ採取するには、 Tomcat起動時の環境変数CATALINA_OPTSに引数-verbose:gcを付加します。 verbose gcが有効な場合、毎回のガーベジコレクションにどれぐらい時間がかかったかが $CATALINA_BASE/logs/catalina.outログファイルに含まれます。

When your JVM is tuned correctly 99% of the time a GC will take less than one second. The remainder will only take a few seconds. Rarely, if ever should a GC take more than 10 seconds.

JVMが正しく調整されていれば、ガーベジコレクションにかかる時間の99%は1秒以内です。 残りは数秒かかることがあります。GCに10秒以上かかることは例外的です。

Make sure that the db connection timeout is set to 10-15 seconds. For the DBCP you set this using the parameter maxWait.

データベース接続のタイムアウトが10-15秒に設定されていることを確認してください。 DBCPの場合はmaxWaitパラメータを使って設定します。

接続を手当たり次第に閉じようとしたときに発生する例外

These can occur when one request gets a db connection from the connection pool and closes it twice. When using a connection pool, closing the connection just returns it to the pool for reuse by another request, it doesn't close the connection. And Tomcat uses multiple threads to handle concurrent requests. Here is an example of the sequence of events which could cause this error in Tomcat:
  Request 1 running in Thread 1 gets a db connection.

  Request 1 closes the db connection.

  The JVM switches the running thread to Thread 2

  Request 2 running in Thread 2 gets a db connection
  (the same db connection just closed by Request 1).

  The JVM switches the running thread back to Thread 1

  Request 1 closes the db connection a second time in a finally block.

  The JVM switches the running thread back to Thread 2

  Request 2 Thread 2 tries to use the db connection but fails
  because Request 1 closed it.
Here is an example of properly written code to use a db connection obtained from a connection pool:
  Connection conn = null;
  Statement stmt = null;  // Or PreparedStatement if needed
  ResultSet rs = null;
  try {
    conn = ... get connection from connection pool ...
    stmt = conn.createStatement("select ...");
    rs = stmt.executeQuery();
    ... iterate through the result set ...
    rs.close();
    rs = null;
    stmt.close();
    stmt = null;
    conn.close(); // Return to connection pool
    conn = null;  // Make sure we don't close it twice
  } catch (SQLException e) {
    ... deal with errors ...
  } finally {
    // Always make sure result sets and statements are closed,
    // and the connection is returned to the pool
    if (rs != null) {
      try { rs.close(); } catch (SQLException e) { ; }
      rs = null;
    }
    if (stmt != null) {
      try { stmt.close(); } catch (SQLException e) { ; }
      stmt = null;
    }
    if (conn != null) {
      try { conn.close(); } catch (SQLException e) { ; }
      conn = null;
    }
  }

これは、ひとつのリクエストが接続プールからデータベース接続をひとつ取得し、2度閉じると発生します。 接続プールを使っている場合、接続を閉じると接続は他のリクエストで再利用するためにプールへ返却され、 接続は閉じられません。また、Tomcatは平行してリクエストを処理するために複数のスレッドを使います。 これはTomcatでこのエラーが発生するイベントのシーケンスの例です:

  スレッド1で実行中のリクエスト1がデータベース接続を取得する

  リクエスト1がデータベース接続を閉じる

  JVMは実行スレッドをスレッド2に切り替える

  スレッド2で実行中のリクエスト2がデータベース接続を取得する
  (リクエスト1が閉じたばかりのデータベース接続とおなじもの)

  JVMが実行スレッドをスレッド1に切り替える

  リクエスト1がfinallyブロック内で2度目のデータベース接続を閉じる

  JVMが実行スレッドをスレッド2に切り替える

  スレッド2のリクエスト2がデータベース接続を閉じようとするが、
  リクエスト1がすでに閉じれているので失敗する
これは接続プールから取得したデータベース接続を使用する正しいコードの記述例です:
  Connection conn = null;
  Statement stmt = null;  // Or PreparedStatement if needed
  ResultSet rs = null;
  try {
    conn = ... 接続プールからの接続の取得 ...
    stmt = conn.createStatement("select ...");
    rs = stmt.executeQuery();
    ... ResultSetの繰り返し ...
    rs.close();
    rs = null;
    stmt.close();
    stmt = null;
    conn.close(); // 接続プールへの返却
    conn = null;  // 2度閉じないことを確認する
  } catch (SQLException e) {
    ... deal with errors ...
  } finally {
    // 常にResultSetとStatementは閉じられ、
    // 接続はプールへ返却されることを確認してください
    if (rs != null) {
      try { rs.close(); } catch (SQLException e) { ; }
      rs = null;
    }
    if (stmt != null) {
      try { stmt.close(); } catch (SQLException e) { ; }
      stmt = null;
    }
    if (conn != null) {
      try { conn.close(); } catch (SQLException e) { ; }
      conn = null;
    }
  }


[訳注: この文書は阿島 哲夫が翻訳し、 小川 環が校正しました。 日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright © 1999-2003, Apache Software Foundation