[Seasar-user:20222] Re: バッチアプリでトランザクションが有効にならない

kubo [E-MAIL ADDRESS DELETED]
2010年 10月 7日 (木) 07:58:59 JST


久保(jflute)です。

おはようございます、高橋さん

>        private static int mainProcedure(){
>                Sample01ServiceImpl service = new Sample01ServiceImpl();
>                service.hogeInsert(container);
>                return service.hogeSelectList(container);
>        }

ここで、Serviceクラスが new されているので、
「S2Container管理外のコンポーネント」になっている
からトランザクションAOPが効いていないように思えます。
ServiceクラスもContainerから取得する形にして
試してみると良いと思います。

バッチアプリでしたら、dbflute-basic-example の
src/test/java/com/.../basic/batch配下にサンプルが
ありますので(トランザクション使ってます)、
こういうときに見比べてみると解決しやすいかも
なのでぜひご参考下さい。

2010/10/7 高橋 伸弘 <[E-MAIL ADDRESS DELETED]>:
> 初めてアップさせていただきす。
> 高橋と申します。よろしくお願い致します。
>
> 現在、S2+dbfluteでJavaバッチアプリケーションのサンプルを作成しています。
>
> サービス単位でトランザクションを切りたいと思っておりますが、
> customaizer.diconのservicecustomaizerにrequiredTxCustomizerを設定してもトラン
> ザクションが
> 効いていない感じです。
>
> 起動時のログをみても「トランザクションが開始されました」のメッセージが出てきま
> せん。
> 論理コネクションの取得の際のtxもnullなので、トランザクションが有効になっていな
> いと思われます。
>
> 処理としては1サービスクラスにinsertとselectのメソッドを作成し、
> Insertメソッド
> 1.insert
> 2.insert
> selectメソッド
> select
> の順に実行しています。
>
> 1回目のinsertと2回目のinsertは同じデータを登録し2回目でエラーとなるようにし
> ていますが、
> 1回目にinsertされたデータがロールバックされません。
> 色々、設定を変えてみましたが、上手くいきません。
> 何かおかしなことをしておりますでしょうか?
> ご指摘いただければ幸いです。
> よろしくお願いします。
>
>
> 開発環境
> ECLIPSE 3.4
> JDK6-20
> S2  2.4.40
> dbflute 0.9.6
>
> <ソース>
> ①主処理
> public class Main {
>        private static S2Container container;
>        private static AccessContext context;
>        private static final int FAIL_SHURYO_CODE = 1;
>        private static final String USER_ID = "BATCH";
>        private static final String PROCESS_ID = "SAMPLE";
>        private static final String S2PATH = "app.dicon";
>        /**
>         * @param args
>         */
>        public static void main(String[] args) {
>                int SUCCESS_SHURYO_CODE = 0;
>                try {
>                        // システムの初期処理
>                        container = S2ContainerFactory.create(S2PATH);
>                        container.init();
>                        new CommonShori().eaInit(context, new Timestamp(System.currentTimeMillis())
>  , USER_ID, PROCESS_ID);
>                        // 初期処理
>                        initializeProcedure();
>                        // 主処理
>                        SUCCESS_SHURYO_CODE = mainProcedure();
>                } catch (Exception e){
>                        e.printStackTrace();
>                        // システムの終了処理
>                        System.exit(FAIL_SHURYO_CODE);
>                } finally {
>                        // システムの終了処理
>                        new CommonShori().eaTerm(container);
>                }
>                // 正常終了メッセージ
>                System.exit(SUCCESS_SHURYO_CODE);
>        }
>        private static void initializeProcedure(){
>        }
>        private static int mainProcedure(){
>                Sample01ServiceImpl service = new Sample01ServiceImpl();
>                service.hogeInsert(container);
>                return service.hogeSelectList(container);
>        }
> }
> ②サービス
> public class Sample01ServiceImpl implements Sample01Service {
>        private static final String MSG_LEVEL_INFO="INFO";
>        public Sample01ServiceImpl(){}
>        @Override
>        public int hogeSelectList(S2Container container) {
>                hogehogeMasterBhv hogehogeMasterBhv = (hogehogeMasterBhv)container.getCompon
> ent(hogehogeMasterBhv.class);
>                hogehogeMasterCB cb = new hogehogeMasterCB();
>                cb.query().sethogehogeid_Equal("00001");
>
>                ListResultBean<hogehogeMaster> listResultBean = hogehogeMasterBhv.selectList
> (cb);
>
>                System.out.println(listResultBean.size());
>                if (listResultBean.size() > 0) {
>                        return 0;
>                }
>                return -1;
>        }
>        @Override
>        public void hogeInsert(S2Container container) {
>                hogehogeMasterBhv hogehogeMasterBhv = (hogehogeMasterBhv)container.getCompon
> ent(hogehogeMasterBhv.class);
>                hogehogeMaster hogehogeMaster = new hogehogeMaster();
>                hogehogeMaster.sethogehogeid("11111");
>                hogehogeMaster.setDocid("33333");
>                hogehogeMasterBhv.insert(hogehogeMaster);
>
>                hogehogeMaster.sethogehogeid("11111");
>                hogehogeMaster.setDocid("33333");
>                hogehogeMasterBhv.insert(hogehogeMaster);
>        }
> }
>
> ③convention.dicon
> <components>
>        <component class="org.seasar.framework.convention.impl.NamingConventionImpl">
>                <initMethod name="addRootPackageName">
>                        <arg>"org.hoge.sampleBatch"</arg>
>                </initMethod>
>        </component>
> </components>
>
> ④creater.dicon
> <components>
>  <include path="customizer.dicon"/>
>  <include path="convention.dicon"/>
>  <component name="daoCreator" class="org.seasar.framework.container.creator.D
> aoCreator"/>
>  <component name="dtoCreator" class="org.seasar.framework.container.creator.D
> toCreator"/>
>  <component name="dxoCreator" class="org.seasar.framework.container.creator.D
> xoCreator"/>
>  <component name="interceptorCreator" class="org.seasar.framework.container.c
> reator.InterceptorCreator"/>
>  <component name="logicCreator" class="org.seasar.framework.container.creator
> .LogicCreator"/>
>  <component name="serviceCreator" class="org.seasar.framework.container.creat
> or.ServiceCreator"/>
> </components>
>
> ⑤customizer.dicon
> <components>
>  <include path="default-customizer.dicon"/>
>  <component name="serviceCustomizer"
>    class="org.seasar.framework.container.customizer.CustomizerChain">
>    <initMethod name="addCustomizer">
>      <arg>requiredTxCustomizer</arg>
>    </initMethod>
>  </component>
>  <component name="logicCustomizer" class="org.seasar.framework.container.cust
> omizer.CustomizerChain">
>    <initMethod name="addCustomizer">
>      <arg>traceCustomizer</arg>
>    </initMethod>
>  </component>
>  <component name="daoCustomizer" class="org.seasar.framework.container.custom
> izer.CustomizerChain">
>    <initMethod name="addCustomizer">
>      <arg>traceCustomizer</arg>
>    </initMethod>
>    <initMethod name="addCustomizer">
>      <arg>s2DaoCustomizer</arg>
>    </initMethod>
>  </component>
>  <component name="dxoCustomizer" class="org.seasar.framework.container.custom
> izer.CustomizerChain">
>    <initMethod name="addCustomizer">
>      <arg>traceCustomizer</arg>
>    </initMethod>
>    <initMethod name="addCustomizer">
>      <arg>s2DxoCustomizer</arg>
>    </initMethod>
>  </component>
>  <component name="csvCustomizer" class="org.seasar.framework.container.custom
> izer.CustomizerChain"/>
> </components>
>
> ⑥jdbc.dicon
> <components namespace="jdbc">
>        <include path="jta.dicon"/>
>        <include path="jdbc-extension.dicon"/>
>        <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
>        <component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory
> ">
>                <arg>
>                        <component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
>                </arg>
>                <property name="fetchSize">100</property>
>        </component>
>        <!-- for Oracle -->
>        <component name="xaDataSource"
>                class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
>                <property name="driverClassName">
>                        "oracle.jdbc.driver.OracleDriver"
>                </property>
>                <property name="URL">
>                        "jdbc:oracle:thin:@k-Tsuzurano:1521:xe"
>                </property>
>                <property name="user">"TEST"</property>
>                <property name="password">"TEST"</property>
>        </component>
>
>        <component name="connectionPool"
>                class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
>                <property name="timeout">600</property>
>                <property name="maxPoolSize">3</property>
>                <property name="allowLocalTx">true</property>
>                <destroyMethod name="close"/>
>        </component>
>
>        <component name="dataSource"
>                class="org.seasar.extension.dbcp.impl.DataSourceImpl"
>        />
> </components>
>
> <実行ログ>
> 2010/10/06 13:15:28.290, DEBUG [main], S2Containerを作成します。path=cooldeplo
> y.dicon, Logger.java:231
> 2010/10/06 13:15:28.410, DEBUG [main], S2Containerを作成しました。path=cooldep
> loy.dicon, Logger.java:231
> 2010/10/06 13:15:28.440, DEBUG [main], S2Containerを作成します。path=app.dicon
> , Logger.java:231
> 2010/10/06 13:15:28.461, DEBUG [main], S2Containerを作成します。path=conventio
> n.dicon, Logger.java:231
> 2010/10/06 13:15:28.531, DEBUG [main], S2Containerを作成しました。path=convent
> ion.dicon, Logger.java:231
> 2010/10/06 13:15:28.551, DEBUG [main], S2Containerを作成します。path=aop.dicon
> , Logger.java:231
> 2010/10/06 13:15:28.651, DEBUG [main], S2Containerを作成しました。path=aop.dic
> on, Logger.java:231
> 2010/10/06 13:15:28.651, DEBUG [main], S2Containerを作成します。path=app_aop.d
> icon, Logger.java:231
> 2010/10/06 13:15:28.711, DEBUG [main], S2Containerを作成しました。path=app_aop
> .dicon, Logger.java:231
> 2010/10/06 13:15:28.711, DEBUG [main], S2Containerを作成します。path=dbflute.d
> icon, Logger.java:231
> 2010/10/06 13:15:28.731, DEBUG [main], S2Containerを作成します。path=j2ee.dico
> n, Logger.java:231
> 2010/10/06 13:15:28.751, DEBUG [main], S2Containerを作成します。path=jta.dicon
> , Logger.java:231
> 2010/10/06 13:15:28.821, DEBUG [main], S2Containerを作成しました。path=jta.dic
> on, Logger.java:231
> 2010/10/06 13:15:28.821, DEBUG [main], S2Containerを作成します。path=jdbc.dico
> n, Logger.java:231
> 2010/10/06 13:15:28.851, DEBUG [main], S2Containerを作成します。path=jdbc-exte
> nsion.dicon, Logger.java:231
> 2010/10/06 13:15:28.881, DEBUG [main], S2Containerを作成しました。path=jdbc-ex
> tension.dicon, Logger.java:231
> 2010/10/06 13:15:29.001, DEBUG [main], S2Containerを作成しました。path=jdbc.di
> con, Logger.java:231
> 2010/10/06 13:15:29.021, DEBUG [main], S2Containerを作成しました。path=j2ee.di
> con, Logger.java:231
> 2010/10/06 13:15:29.622, DEBUG [main], S2Containerを作成しました。path=dbflute
> .dicon, Logger.java:231
> 2010/10/06 13:15:29.632, DEBUG [main], S2Containerを作成します。path=dxo.dicon
> , Logger.java:231
> 2010/10/06 13:15:29.642, DEBUG [main], S2Containerを作成します。path=dxo-built
> in-converters.dicon, Logger.java:231
> 2010/10/06 13:15:29.712, DEBUG [main], S2Containerを作成しました。path=dxo-bui
> ltin-converters.dicon, Logger.java:231
> 2010/10/06 13:15:29.712, DEBUG [main], S2Containerを作成します。path=dxo-tiger
> -converters.dicon, Logger.java:231
> 2010/10/06 13:15:29.742, DEBUG [main], S2Containerを作成しました。path=dxo-tig
> er-converters.dicon, Logger.java:231
> 2010/10/06 13:15:29.752, DEBUG [main], S2Containerを作成しました。path=dxo.dic
> on, Logger.java:231
> 2010/10/06 13:15:29.782, DEBUG [main], S2Containerを作成しました。path=app.dic
> on, Logger.java:231
> 2010/10/06 13:15:29.782, DEBUG [main], S2Containerを作成します。path=cooldeplo
> y-autoregister.dicon, Logger.java:231
> 2010/10/06 13:15:29.802, DEBUG [main], S2Containerを作成します。path=customize
> r.dicon, Logger.java:231
> 2010/10/06 13:15:29.812, DEBUG [main], S2Containerを作成します。path=default-c
> ustomizer.dicon, Logger.java:231
> 2010/10/06 13:15:29.822, DEBUG [main], S2Containerを作成します。path=std-custo
> mizer.dicon, Logger.java:231
> 2010/10/06 13:15:29.843, DEBUG [main], S2Containerを作成します。path=std-custo
> mizer-tiger.dicon, Logger.java:231
> 2010/10/06 13:15:29.853, DEBUG [main], S2Containerを作成しました。path=std-cus
> tomizer-tiger.dicon, Logger.java:231
> 2010/10/06 13:15:29.883, DEBUG [main], S2Containerを作成しました。path=std-cus
> tomizer.dicon, Logger.java:231
> 2010/10/06 13:15:29.893, DEBUG [main], S2Containerを作成しました。path=default
> -customizer.dicon, Logger.java:231
> 2010/10/06 13:15:29.913, DEBUG [main], S2Containerを作成しました。path=customi
> zer.dicon, Logger.java:231
> 2010/10/06 13:15:29.913, DEBUG [main], S2Containerを作成します。path=creator.d
> icon, Logger.java:231
> 2010/10/06 13:15:29.933, DEBUG [main], S2Containerを作成しました。path=creator
> .dicon, Logger.java:231
> 2010/10/06 13:15:29.953, DEBUG [main], S2Containerを作成しました。path=cooldep
> loy-autoregister.dicon, Logger.java:231
> 2010/10/06 13:15:30.003, INFO  [main], ...Initializing DBFlute components!, DB
> FluteInitializer.java:28
> 2010/10/06 13:15:30.003, INFO  [main], ...Initializing DBFlute components!, DB
> FluteInitializer.java:28
> 2010/10/06 13:15:30.023, INFO  [main], ...Closing the sqlLogRegistry., TnSqlLo
> gRegistry.java:145
> 2010/10/06 13:15:30.023, INFO  [main], ...Closing the sqlLogRegistry., TnSqlLo
> gRegistry.java:145
> 2010/10/06 13:15:30.043, INFO  [main], ...Locking the configuration of DBFlute
> !, DBFluteConfig.java:307
> 2010/10/06 13:15:30.043, INFO  [main], ...Locking the configuration of DBFlute
> !, DBFluteConfig.java:307
> 2010/10/06 13:15:30.143, DEBUG [main], クラス(org.hoge.sampleBatch.service.imp
> l.Sample01ServiceImpl[sample01Service])のコンポーネント定義を登録します, Logge
> r.java:231
> 2010/10/06 13:15:30.774, DEBUG [main], ...Setting up column columns of hogehog
> e_MASTER before INSERT!, ImplementedCommonColumnAutoSetupper.java:107
> 2010/10/06 13:15:30.774, DEBUG [main], ...Setting up column columns of hogehog
> e_MASTER before INSERT!, ImplementedCommonColumnAutoSetupper.java:107
> 2010/10/06 13:15:30.924, DEBUG [main], ...Initializing sqlExecution for the ke
> y 'hogehoge_MASTER:insert(hogehogeMaster)', XLog.java:38
> 2010/10/06 13:15:30.924, DEBUG [main], ...Initializing sqlExecution for the ke
> y 'hogehoge_MASTER:insert(hogehogeMaster)', XLog.java:38
> 2010/10/06 13:15:31.715, DEBUG [main], 物理的なコネクションを取得しました, Log
> ger.java:231
> 2010/10/06 13:15:31.775, DEBUG [main], 論理的なコネクションを取得しました。tx=
> null, Logger.java:231
> 2010/10/06 13:15:31.825, DEBUG [main], 論理的なコネクションを閉じました。tx=nu
> ll, Logger.java:231
> 2010/10/06 13:15:31.865, DEBUG [main], SqlExecution Initialization Cost: [00m0
> 0s941ms], XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main], SqlExecution Initialization Cost: [00m0
> 0s941ms], XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main], /======================================
> ======================================, XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main], /======================================
> ======================================, XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main],
>               hogehogeMasterBhv.insert(), XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main],
>               hogehogeMasterBhv.insert(), XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main],
>               ======================/, XLog.java:38
> 2010/10/06 13:15:31.865, DEBUG [main],
>               ======================/, XLog.java:38
> 2010/10/06 13:15:31.895, DEBUG [main], Sample01ServiceImpl.hogeInsert():41 ->
> ..., XLog.java:38
> 2010/10/06 13:15:31.895, DEBUG [main], Sample01ServiceImpl.hogeInsert():41 ->
> ..., XLog.java:38
> 2010/10/06 13:15:31.895, DEBUG [main], 論理的なコネクションを取得しました。tx=
> null, Logger.java:231
> 2010/10/06 13:15:31.936, DEBUG [main],
> insert into hogehoge_MASTER (hogehogeID, DOCID, INS_DATE_TIME, INS_USER_CODE,
> INS_PROCESS, UPD_DATE_TIME, UPD_USER_CODE, UPD_PROCESS, VERSION_NO)
>  values ('11111', '33333', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMP
> LE', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMPLE', 0), QLog.java:38
> 2010/10/06 13:15:31.936, DEBUG [main],
> insert into hogehoge_MASTER (hogehogeID, DOCID, INS_DATE_TIME, INS_USER_CODE,
> INS_PROCESS, UPD_DATE_TIME, UPD_USER_CODE, UPD_PROCESS, VERSION_NO)
>  values ('11111', '33333', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMP
> LE', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMPLE', 0), QLog.java:38
> org.seasar.dbflute.exception.EntityAlreadyExistsException: Look! Read the mess
> age below.
> /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> The entity already exists on the database!
>
> [Advice]
> Please confirm the primary key whether it already exists on the database.
> And confirm the unique constraint for other columns.
>
> [SQLState]
> 23000
>
> [ErrorCode]
> 1
>
> [SQLException]
> org.seasar.framework.exception.SSQLException
> [ESSR0072]SQLで例外(SQL=[insert into hogehoge_MASTER (hogehogeID, DOCID, INS_D
> ATE_TIME, INS_USER_CODE, INS_PROCESS, UPD_DATE_TIME, UPD_USER_CODE, UPD_PROCES
> S, VERSION_NO)
>  values (?, ?, ?, ?, ?, ?, ?, ?, ?)], Message=[1], ErrorCode=23000, SQLState={
> 3})が発生しました
>
> [NextException]
> java.sql.SQLException
> ORA-00001: 一意制約(TEST.hogehoge_MASTER_PK)に反しています
>
> [Behavior]
> Sample01ServiceImpl.hogeInsert():41 -> hogehogeMasterBhv.insert()...
>
> [Statement]
> org.seasar.extension.jdbc.impl.PreparedStatementWrapper
>
> [Display SQL]
> insert into hogehoge_MASTER (hogehogeID, DOCID, INS_DATE_TIME, INS_USER_CODE,
> INS_PROCESS, UPD_DATE_TIME, UPD_USER_CODE, UPD_PROCESS, VERSION_NO)
>  values ('11111', '33333', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMP
> LE', timestamp '2010-10-06 13:15:30.674', 'BATCH', 'SAMPLE', 0)
> * * * * * * * * * */
>        at org.seasar.dbflute.resource.SQLExceptionHandler.throwEntityAlreadyExistsEx
> ception(SQLExceptionHandler.java:132)
>        at org.seasar.dbflute.resource.SQLExceptionHandler.handleSQLException(SQLExce
> ptionHandler.java:55)
>        at org.seasar.dbflute.s2dao.sqlhandler.TnBasicHandler.handleSQLException(TnBa
> sicHandler.java:235)
>        at org.seasar.dbflute.s2dao.sqlhandler.TnBasicHandler.executeUpdate(TnBasicHa
> ndler.java:275)
>        at org.seasar.dbflute.s2dao.sqlhandler.TnAbstractAutoHandler.execute(TnAbstra
> ctAutoHandler.java:87)
>        at org.seasar.dbflute.s2dao.sqlhandler.TnAbstractAutoHandler.execute(TnAbstra
> ctAutoHandler.java:69)
>        at org.seasar.dbflute.s2dao.sqlcommand.TnInsertAutoDynamicCommand.execute(TnI
> nsertAutoDynamicCommand.java:64)
>        at org.seasar.dbflute.bhv.core.BehaviorCommandInvoker.executeSql(BehaviorComm
> andInvoker.java:321)
>        at org.seasar.dbflute.bhv.core.BehaviorCommandInvoker.dispatchInvoking(Behavi
> orCommandInvoker.java:175)
>        at org.seasar.dbflute.bhv.core.BehaviorCommandInvoker.invoke(BehaviorCommandI
> nvoker.java:141)
>        at org.seasar.dbflute.bhv.AbstractBehaviorReadable.invoke(AbstractBehaviorRea
> dable.java:886)
>        at org.hogehoge.sample.dbflute.bsbhv.BshogehogeMasterBhv.delegateInsert(Bshog
> ehogeMasterBhv.java:492)
>        at org.hogehoge.sample.dbflute.bsbhv.BshogehogeMasterBhv.insert(BshogehogeMas
> terBhv.java:269)
>        at org.hoge.sampleBatch.service.impl.Sample01ServiceImpl.hogeInsert(Sample01S
> erviceImpl.java:41)
>        at org.hoge.sampleBatch.sample01.Main.mainProcedure(Main.java:67)
>        at org.hoge.sampleBatch.sample01.Main.main(Main.java:44)
> Caused by: org.seasar.framework.exception.SSQLException: [ESSR0072]SQLで例外(S
> QL=[insert into hogehoge_MASTER (hogehogeID, DOCID, INS_DATE_TIME, INS_USER_CO
> DE, INS_PROCESS, UPD_DATE_TIME, UPD_USER_CODE, UPD_PROCESS, VERSION_NO)
>  values (?, ?, ?, ?, ?, ?, ?, ?, ?)], Message=[1], ErrorCode=23000, SQLState={
> 3})が発生しました
>        at org.seasar.extension.jdbc.impl.PreparedStatementWrapper.wrapException(Prep
> aredStatementWrapper.java:72)
>        at org.seasar.extension.jdbc.impl.PreparedStatementWrapper.wrapException(Prep
> aredStatementWrapper.java:67)
>        at org.seasar.extension.jdbc.impl.PreparedStatementWrapper.executeUpdate(Prep
> aredStatementWrapper.java:91)
>        at org.seasar.dbflute.s2dao.sqlhandler.TnBasicHandler.executeUpdate(TnBasicHa
> ndler.java:273)
>        ... 12 more
> Caused by: java.sql.SQLException: ORA-00001: 一意制約(TEST.hogehoge_MASTER_PK)
> に反しています
>
> 添付ファイル
>
>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>
>


Seasar-user メーリングリストの案内