S2JTA と S2DBCP をスタンドアロンで使う

Seasar2 が提供している JTA の実装である S2JTA や,JTA と連携するコネクションプールである S2DBCP は,DI コンテナとは独立に使うことができます.
使い方も結構簡単です.


まず JTA の場合,TransactionManagernew するだけ.

import org.seasar.extension.jta.TransactionManagerImpl;

TransactionManager tm = new TransactionManagerImpl();

最低限必要なのはこれだけ.
もし UserTransaction も使うならこれを追加.

import org.seasar.extension.jta.UserTransactionImpl;

UserTransaction ut = new UserTransactionImpl(tm);

普通は必要ないと思いますが,JTA1.1 で追加された TransactionSynchronizationRegistry も使うならこれも追加.

import org.seasar.extension.jta.TransactionSynchronizationRegistryImpl;

TransactionSynchronizationRegistry tsr = new TransactionSynchronizationRegistryImpl(tm);

JTA 側はこれで終了.


コネクションプール側は,まずは XADataSource を用意.

import org.seasar.extension.dbcp.impl.XADataSourceImpl;

XADataSourceImpl xads = new XADataSourceImpl();
xads.setDriverClassName("org.h2.Driver");
xads.setURL("jdbc:h2:mem:");
xads.setUser("");
xads.setPassword("");

続けてコネクションプールを用意.

import org.seasar.extension.dbcp.impl.ConnectionPoolImpl;

ConnectionPoolImpl pool = new ConnectionPoolImpl();
pool.setTransactionManager(tm);
pool.setXADataSource(xads);

最後にアプリから利用する DataSource を用意.

import org.seasar.extension.dbcp.impl.DataSourceImpl;

DataSourceImpl ds = new DataSourceImpl(pool);

以上.
Seasar2 で使う場合はこれらを dicon に書いてるだけです.


実際に使う場合.

ut.begin();
Connection con = ds.getConnection();
...
ut.commit();


依存ライブラリは以下になります.

  • s2-framework-2.4.x.jar
  • s2-extension-2.4.x.jar
  • geronimo-jta_1.1_spec-1.0.jar (java.net の jta-1.1.jar でも可)
  • commons-logging-1.1.jar (SLF4J の jcl-over-slf4j でも可)

S2JTA と S2DBCP だけ使うなら,OGNL や Javassist 等の Jar は不要です.


Doma で使うなら例えばこんな Config を作ってみるとか.

public class JtaConfig extends DomaAbstractConfig {
    protected static TransactionManager tm;
    protected static UserTransaction ut;
    protected static XADataSourceImpl xads;
    protected static ConnectionPoolImpl pool;
    protected static DataSourceImpl ds;

    static {
        tm = new TransactionManagerImpl();
        ut = new UserTransactionImpl(tm);
        xads = new XADataSourceImpl();
        xads.setDriverClassName("org.h2.Driver");
        xads.setURL("jdbc:h2:mem:");
        pool = new ConnectionPoolImpl();
        pool.setTransactionManager(tm);
        pool.setXADataSource(xads);
        ds = new DataSourceImpl(pool);
    }

    public UserTransaction getUserTransaction() {
        return ut;
    }

    @Override
    public DataSource getDataSource() {
        return ds;
    }

    @Override
    public Dialect getDialect() {
        return new H2Dialect();
    }
}

複数の DataSource が必要なら JTA とコネクションプールは分けるとかしないといけませんが,その辺は必要に応じてということで.


P.S
JavaSE + CDI (JBoss Weld SE) 環境で JTA を使うための JUnit CDI Extensions for JTA はまさに上記のことをやってます.