| 本ドキュメントは`S2.2.10`について記述しています．旧バージョンについては該当バージョンの配布ファイルに含まれているドキュメントを参照してください． S2DBCPの機能を使って、コネクションプーリングを実現できます。JTAと連動するので、トランザクション中にコネクションを取得し閉じるということを何度か行っても、トランザクションは維持されます。JDBCで行っていたようなトランザクションを維持したいがために複数のクラスでコネクションを持ちまわるようなことはもう必要なくなります。S2Txを使えば、トランザクションもAspectで自動的に処理することができます。 ## セットアップ XADataSource、ConnectionPoolの設定をおこないます。JDBC DriverがXADataSourceの機能を提供している場合は、 それをそのまま使えますが、提供されていない場合、S2で用意しているXADataSourceImplを使って、XAの機能をエミュレートします。 ### org.seasar.extension.dbcp.impl.XADataSourceImpl
プロパティ | 説明 | 例
--- | --- | ---
`driverClassName` | JDBC Driverのクラス名 | `"oracle.jdbc.driver.OracleDriver"`
`URL` | RDBMS固有のURL | `"jdbc:oracle:thin:@xxx:1521:yyy"`
`user` | ユーザ名 | `"hoge"`
`password` | パスワード | `"password"`
### org.seasar.extension.dbcp.impl.ConnectionPoolImpl
プロパティ | 説明 | 例
--- | --- | ---
`XADataSource` | XADataSourceのインスタンスを設定します。S2Containerで設定する場合は、XADataSourceのコンポーネント名を設定します。 必須です。 | `xaDataSource`
`transactionManager` | TransactionManagerのインスタンスを設定します。S2Containerで設定する場合は、TransactionManagerのコンポーネント名を設定します。 必須です。 | `transactionManager`
`timeout` | プールに戻されたコネクションがここで指定された秒数以上未使用だった場合、物理的にクローズされて破棄されます。 デフォルトは600(10分)です。 | `600`
`maxPoolSize` | 同時にアクティブになれる コネクションの数を指定します。 この数を超える要求があると、コネクションがプールに返されるまで その要求はブロックされます。 0を設定するとコネクションはプールされず、コネクションの取得要求はブロックされません。 デフォルトは10です。 | `10`
`allowLocalTx` | JTAによって制御されない、JDBCのローカルトランザクションを許可する (`true`) しない (`false`) を指定します。 `false`を指定すると、JTAによるトランザクションが開始されていない状態でコネクションの取得が行われた場合に例外 (`java.lang.IllegalStateException`) がスローされます。 開発時に`false`を指定すると、S2Txが提供するトランザクション・インターセプタの設定漏れを確実に検出することができます。 デフォルトは`true`です。 | `true`
コンポーネントの設定は以下のようになります。環境に合わせて書き換えてください。 ### j2ee.dicon
    <components namespace="j2ee">
        <component name="transactionManager"
            class="org.seasar.extension.jta.TransactionManagerImpl"/>
        <component name="requiredTx"
            class="org.seasar.extension.tx.RequiredAdvice"/>
        <component name="requiresNewTx"
            class="org.seasar.extension.tx.RequiresNewAdvice"/>
        <component name="mandatoryTx"
            class="org.seasar.extension.tx.MandatoryAdvice"/>

        <component name="xaDataSource"
            class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
            <property name="driverClassName">
                "oracle.jdbc.driver.OracleDriver"
            </property>
            <property name="URL">
                "jdbc:oracle:thin:@xxx:1521:yyy"
            </property>
            <property name="user">"aaa"</property>
            <property name="password">"bbb"</property>
        </component>
        <component name="connectionPool"
            class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
            <property name="timeout">600</property>
            <property name="maxPoolSize">10</property>
            <property name="allowLocalTx">true</property>
            <destroyMethod name="close"/>
        </component>
        <component name="dataSource"
            class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>

    </components>
## Example ### EmployeeDao.java
    package examples.dbcp;

    import java.sql.SQLException;

    public interface EmployeeDao {

        public String getEmployeeName(int empno) throws SQLException;
    }
#### EmployeeDaoImpl.java
    package examples.dbcp;

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    import javax.sql.DataSource;

    public class EmployeeDaoImpl implements EmployeeDao {

        private DataSource dataSource_;

        public EmployeeDaoImpl(DataSource dataSource) {
            dataSource_ = dataSource;
        }

        public String getEmployeeName(int empno) throws SQLException {
            String ename = null;
            Connection con = dataSource_.getConnection();
            try {
                PreparedStatement ps = con.prepareStatement(
                    "SELECT ename FROM emp WHERE empno = ?");
                try {
                    ps.setInt(1, empno);
                    ResultSet rs = ps.executeQuery();
                    try {
                        if (rs.next()) {
                            ename = rs.getString("ename");
                        }
                    } finally {
                        rs.close();
                    }
                } finally {
                    ps.close();
                }
            } finally {
                con.close();
            }
            return ename;
        }
    }
### EmployeeService.java
    package examples.dbcp;

    import java.sql.SQLException;

    public interface EmployeeService {

        public String getEmployeeName(int empno) throws SQLException;
    }
### EmployeeServiceImpl.java
    package examples.dbcp;

    import java.sql.SQLException;

    public class EmployeeServiceImpl implements EmployeeService {

        private EmployeeDao dao_;

        public EmployeeServiceImpl(EmployeeDao dao) {
            dao_ = dao;
        }

        public String getEmployeeName(int empno) throws SQLException {
            return dao_.getEmployeeName(empno);
        }
    }
### Employee.dicon
    <components>
        <include path="j2ee.dicon"/>
        <component class="examples.dbcp.EmployeeDaoImpl"/>
        <component class="examples.dbcp.EmployeeServiceImpl">
            <aspect>j2ee.requiredTx</aspect>
        </component>
    </components>
### EmployeeClient.java
    package examples.dbcp;

    import java.sql.SQLException;

    import org.seasar.framework.container.S2Container;
    import org.seasar.framework.container.factory.S2ContainerFactory;

    public class EmployeeClient {

        private static final String PATH =
            "examples/dbcp/Employee.dicon";

        public static void main(String[] args) {
            S2Container container = S2ContainerFactory.create(PATH);
            container.init();
            try {
                EmployeeService service = (EmployeeService)
                container.getComponent(EmployeeService.class);
                System.out.println(service.getEmployeeName(7788));
            } catch (SQLException ex) {
                ex.printStackTrace();
            } finally {
                container.destroy();
            }
        }
    }
### 実行結果
    DEBUG 2004-03-21 12:51:35,653 [main] Transaction.begin()
    DEBUG 2004-03-21 12:51:37,075 [main] Transaction.commit()
    SCOTT
これまで、JTAやJTAと連動したコネクションプールに対して、敷居が高いなぁと感じていた方も、POJOでこんなに簡単に利用できるということが分かっていただけたと思います。 |
| © Copyright The Seasar Foundation and the others 2004, all rights reserved.