JOTMのセットアップ手順(JavaSE)
JOTMを使用してJTAをJavaSEで使用する手順です。DBはApache Derbyを使用して、JDBCでInsertを行うところまでを説明します。なお、JTAやApache Derbyについての説明はしません。
Apache Derbyのダウンロード、セットアップ、データベースとテーブルの作成
Apache Derbyからファイルをダウンロードして、適当なフォルダに展開します。
%DERBY%/bin/startNetworkServer.batを実行して、Apache Derbyを起動します。
%DERBY%/bin/ij.batを実行します。connectコマンドを使用して、データベースを作成 & 接続します。
connect 'jdbc:derby://localhost:1527/foo;create=true';
create table文を実行して、テーブルを作成します。
create table foo ( id integer primary key, name varchar(100) not null )
JOTMのダウンロード、セットアップ
JOTMからファイルをダウンロードして、適当なフォルダに展開します。
jarファイルがたくさんありますが、JTAを使用するためには次のjarファイルをクラスパスに追加します。
- %JOTM%/lib/derbyclient.jar
- %JOTM%/lib/jotm-client.jar
- %JOTM%/lib/log4j.jar
- %JOTM%/lib/ow2-jta-1.1-spec.jar
- %JOTM%/lib/xapool.jar
また、次のpropertiesファイルをクラスパスに追加します(ソースフォルダへの追加で良いかと)。
- %JOTM%/conf/carol.properties
- %JOTM%/conf/jotm.properties
- %JOTM%/conf/log4j.properties
コーディング
package foo; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.XAConnection; import javax.transaction.UserTransaction; import org.enhydra.jdbc.standard.StandardXADataSource; import org.objectweb.jotm.Jotm; import org.objectweb.transaction.jta.TMService; public class Foo { private static final String JDBC_URL = "jdbc:derby://localhost:1527/foo"; private static final String JDBC_DRIVER = "org.apache.derby.jdbc.ClientDriver"; private static final String JDBC_USER = "APP"; private static final String JDBC_PASSWORD = "APP"; private static final String USER_TRANSACTION_JNDI_NAME = "UserTransaction"; private static TMService jotm; private static StandardXADataSource ds; public static void main(String[] args) throws Exception { System.setProperty("java.naming.factory.initial", "org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory"); System.setProperty("java.naming.provider.url", "rmi://localhost:1099"); try { Foo.init(); Context ctx = new InitialContext(); UserTransaction utx = (UserTransaction) ctx.lookup(Foo.USER_TRANSACTION_JNDI_NAME); try { utx.begin(); Foo.insert(1, "one"); Foo.insert(2, "two"); utx.rollback(); } catch (Exception e) { utx.rollback(); e.printStackTrace(); } } finally { Foo.stop(); System.exit(0); } } private static void init() throws NamingException, SQLException { Foo.jotm = new Jotm(true, false); InitialContext ctx = new InitialContext(); ctx.rebind(Foo.USER_TRANSACTION_JNDI_NAME, Foo.jotm.getUserTransaction()); Foo.ds = new StandardXADataSource(); Foo.ds.setDriverName(Foo.JDBC_DRIVER); Foo.ds.setUrl(Foo.JDBC_URL); Foo.ds.setTransactionManager(Foo.jotm.getTransactionManager()); } private static Connection getConnection() throws SQLException { XAConnection con = Foo.ds.getXAConnection(Foo.JDBC_USER, Foo.JDBC_PASSWORD); return con.getConnection(); } private static void insert(int id, String name) throws SQLException { Connection con = Foo.getConnection(); try { PreparedStatement ps = con.prepareStatement("insert into foo values (?, ?)"); try { ps.setInt(1, id); ps.setString(2, name); ps.executeUpdate(); } finally { ps.close(); } } finally { con.close(); } } private static void stop() throws NamingException { InitialContext ctx = new InitialContext(); ctx.unbind(Foo.USER_TRANSACTION_JNDI_NAME); } }
ポイントは次の通りです。