読者です 読者をやめる 読者になる 読者になる


S2JDBCでJNDI経由だとロールバックが正常に処理されない!?

現場にて起きている怪現象。

構成は、SAStruts(1.0.4-sp1) + S2JDBC(2.4.28) + Tomcat(6.0.18) + Oracle11g。

jdbc.diconの設定を、org.seasar.extension.dbcp.impl.XADataSourceImpl から javax.sql.DataSource に変えると、ActionクラスでException発生
時に正常にロールバックしません。

S2JDBCが悪いのか、diconの書き方が悪いのか、Tomcatのserver.xmlの書き方が悪いのかのどれかと思うのですが、どうも後ろの2つは違うっぽい。

どなたかご存知の方はいらっしゃいますでしょうか。。。
#ギブアップ気味

以下、ソースと設定ファイルです。

サンプルのActionクラス

2つのテーブルをINSERTやUPDATEして、わざとRuntimeExceptionをthrowしてロールバックを発生しています。

public class IndexAction {

	@SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(IndexAction.class);

	@Resource
	protected JdbcManager jdbcManager;

	@Execute(input = "/index.jxp")
	public String index() {
		jdbcManager.callBySql("UPDATE tbl_hoge SET flg=0").execute();
		jdbcManager.callBySql("INSERT INTO tbl_hoge2 VALUES ('aaa', 'a', 10, 10, null, null)").execute();

		throw new RuntimeException("ロールバックテスト");
	}

}

正常にロールバックする方のjdbc.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
	"http://www.seasar.org/dtd/components21.dtd">
<components namespace="jdbc">
	<include path="jta.dicon"/>

	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"oracle.jdbc.driver.OracleDriver"
		</property>
		<property name="URL">
			"jdbc:oracle:thin:@127.0.0.1:1521:hogehoge"
		</property>
		<property name="user">"oraora"</property>
		<property name="password">"oraora"</property>
	</component>

	<component name="connectionPool"
		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
		<property name="timeout">1800</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>

正常にロールバックしない方のjdbc.dicon と server.xml

jdbc.dicon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
	"http://www.seasar.org/dtd/components21.dtd">
<components namespace="jdbc">
	<include path="jta.dicon"/>

	<component name="DataSource"
		class="javax.sql.DataSource">
		@org.seasar.extension.j2ee.JndiResourceLocator@lookup("java:comp/env/jdbc/hoge")
	</component>
</components>
server.xml (Tomcat)
<GlobalNamingResources>
  <Resource
      name="jdbc/hoge"
      type="javax.sql.DataSource"
      username="oraora"
      password="oraora"
      driverClassName="oracle.jdbc.driver.OracleDriver"
      maxIdle="5"
      maxWait="10000"
      validationQuery="select 1 from dual"
      url="jdbc:oracle:thin:@127.0.0.1:1521:hogehoge"
      maxActive="10"/>
</GlobalNamingResources>

 〜中略〜

<Context path="/" docBase="hogedoc">
    <ResourceLink global="jdbc/hoge" name="jdbc/hoge" type="javax.sql.DataSource"/>
</Context>
出力されているログ

ロールバックしましたという記述はあります。。

DEBUG 2009-06-12 11:46:37,062 [http-8080-2] BEGIN IndexAction#index()
DEBUG 2009-06-12 11:46:37,078 [http-8080-2] トランザクションを開始しました。tx=[FormatId=4360, GlobalId=1244774797078/0, BranchId=]
DEBUG 2009-06-12 11:46:37,093 [http-8080-2] UPDATE tbl_hoge SET flg=0
DEBUG 2009-06-12 11:46:38,734 [http-8080-2] INSERT INTO tbl_hoge2 VALUES ('aaa', 'a', 10, 10, null, null)
DEBUG 2009-06-12 11:46:38,750 [http-8080-2] トランザクションをロールバックしました。tx=[FormatId=4360, GlobalId=1244774797078/0, BranchId=]
2009-06-12 11:46:38,750 [http-8080-2] WARN  ActionThrowableInterceptor - ロールバックテスト
DEBUG 2009-06-12 11:46:38,781 [http-8080-2] END IndexAction#index() : null

解決!?

jdbc.diconを以下のように書き直すと直りました。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
	"http://www.seasar.org/dtd/components21.dtd">
<components namespace="jdbc">
	<include path="jta.dicon"/>

	<component name="xaDataSource"
	           class="org.seasar.extension.dbcp.impl.DataSourceXADataSource">
		<property name="dataSourceName">"java:comp/env/jdbc/hoge"</property>
	</component>
	<component name="connectionPool"
               class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
        <property name="maxPoolSize">0</property>
	</component>
	<component name="DataSource"
		class="org.seasar.extension.dbcp.impl.DataSourceImpl"
	/>
</components>

DataSourceXADataSourceクラスを使うのがミソのようです。

しかし・・・

ヌルポで落ちた・・・

ログに変なものがでてました。

DEBUG 2009-06-12 18:43:08,703 [main] S2Containerを作成しました。path=customizer.dicon
DEBUG 2009-06-12 18:43:08,703 [main] S2Containerを作成します。path=creator.dicon
DEBUG 2009-06-12 18:43:08,734 [main] S2Containerを作成しました。path=creator.dicon
DEBUG 2009-06-12 18:43:08,734 [main] S2Containerを作成しました。path=cooldeploy-autoregister.dicon
WARN  2009-06-12 18:43:08,968 [main] org.seasar.extension.jdbc.manager.JdbcManagerImplのプロパティ(dataSource)が見つからないので設定をスキップします
DEBUG 2009-06-12 18:43:08,984 [main] クラス(hoge..dto.print.IlfPrintSearchResultDto[print_ilfPrintSearchResultDto])のコンポーネント定義を登録します
DEBUG 2009-06-12 18:43:08,984 [main] クラス(hoge..dto.SessionDto[sessionDto])のコンポーネント定義を登録します
DEBUG 2009-06-12 18:43:09,031 [main] クラス(hoge..interceptor.ActionThrowableInterceptor[actionThrowableInterceptor])のコンポーネント定義を登録します
DEBUG 2009-06-12 18:43:09,046 [main] クラス(hoge..interceptor.AuthenticationInterceptor[authenticationInterceptor])のコンポーネント定義を登録します
DEBUG 2009-06-12 18:43:09,062 [main] クラス(hoge..interceptor.OperationTraceInterceptor[operationTraceInterceptor])のコンポーネント定義を登録します

わかった

DataSourceの定義が抜けてました。
上記に追記修正しました。
DataSourceXADataSource、手ごわかった。。。