現場にて起きている怪現象。
構成は、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、手ごわかった。。。