[Seasar-user:20860] Re: Seasar2.4 トランザクションに関する質問です

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2011年 7月 22日 (金) 17:30:35 JST


小林 (koichik) です.

> public TransactionTestServiceImpl() { };
>  
> public void method(XXXXXX xxxxxx) {
>  
>     S2Container container = S2ContainerFactory.create("XXX/transaction_dao.dicon");
> 
>     TransactionTestDao transactionTestDao = (TransactionTestDao) container.
>             getComponent("TransactionTestDao");

このようにサービスの中でコンテナを作成してはいけません。
これだと、サービスのインスタンスを管理している S2Container とは全く
関係のない S2Container が作成されてしまいます。
そのため、サービスのメソッドが呼び出された際に開始されるトランザクションは
この Dao には適用されません。

public class TransactionTestServiceImpl implements TransactionTestService {

  // このフィールドには S2 によって Dao のインスタンスが設定される
  public TransactionTestDao transactionTestDao;

  public void method(XXXXXX xxxxxx) {
    transactionTestDao.addSQL1(xxxxxx);
    ...

としてください。
基本的に、アプリケーションで S2Container を作成する必要はありません。
Web アプリなら S2 または Web フレームワークが提供する Servlet 等が
S2Container を作成します。
バッチ等の場合は main() を持つクラス等で一回だけ S2Container を
作成することになります。その場合でも、S2Container で管理される
インスタンスの中で S2Container を作成することはありません。


Date: Fri, 22 Jul 2011 11:33:24 +0900 (JST)
From: [E-MAIL ADDRESS DELETED]
Subject: [Seasar-user:20858] Seasar2.4 トランザクションに関する質問です

> 社納と申します。
> 
> 
>  
> トランザクションに関して伺いたい事があり、メールさせて頂きました。
>  
> 今、S2Container 2.4.42 、 s2-dao-1.0.51 、 PostgreSQL 8.3.9 、 Tomcat6.0.26
> の組み合わせで、Webアプリケーションを作成しております。
>  
> j2ee.requiredTx を適用させ、複数のSQLを一つのトランザクションにまとめたいのですが、
> 途中でエラーを発生させてみると、エラー前のSQL実行結果はロールバックできておらず、
> 各SQL文単位でコミットされてしまい困っております。
>  
>  
> もっとも、ログを見る限りでは
>  
>     「トランザクションを開始しました」
>  
> の後に複数のSQLが実行されている事が確認でき、さらに、エラーを発生させた箇所で
>  
>     「トランザクションをロールバックしました」
>  
> と表示されており、何も問題無いように見えます。
> これは、そもそも JTAによるトランザクションが開始できていないのかと考え、
> jdbc.dicon の "allowLocalTx" を true から false に変えてみると、
> 果たして「[ESSR0311]トランザクションが開始されていません」として例外がスローされたのですが、
> その例外をgetClass()で調べてみると
> http://s2container.seasar.org/2.4/ja/jdbc.html#S2DBCPに記載されている
>  
>     java.lang.IllegalStateException
>  
> ではなく、
>  
>     org.seasar.framework.exception.SIllegalStateException
>  
> という前者を継承したクラスであり、Webサイトの記載と異なるという点で、
> JTA云々以前に何か間違った事をしているのではないかと不安になりました。
>  
>  
> これは、設定を間違えているのでしょうか?
> 又、JTAによるトランザクションが開始できていないのは確かで
> その原因が下記のコードから判断できるようでしたら、ご指摘頂けないでしょうか?
>  
> 以上、宜しくお願い申し上げます。
>  
>  
>  
> *-*-*-*-*-*-*-*-*-*-*-*-*-*
> 
> 
> ////////// “処理の最初に呼ばれるメソッド” //////////
>  
>>>> S2Container container =
>         S2ContainerFactory.create("XXX/transaction_service.dicon");
> TransactionTestService transactionTestService =
>         (TransactionTestServiceImpl) container.getComponent("TransactionTestService");
>  
> transactionTestService.method(xxxxxx);
>>>>  
>  
>  
>  
> ////////// transaction_service.dicon ////////// 
>  
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
> <components>
>  
>     <include path="j2ee.dicon" />
>     
>     <component name="TransactionTestService" class="XXX.XXX.impl.TransactionTestServiceImpl">
>           <aspect>j2ee.requiredTx</aspect>
>     </component>
>  
> </components>
>  
>  
>  
>  
> ////////// TransactionTestService.java ////////// 
>  
> public interface TransactionTestService {
>  
>     void method(XXXXXX xxxxxx);
> }
>  
>  
>  
>  
> ////////// TransactionTestServiceImpl.java ////////// 
>  
>>>> /** コンストラクタ. */
> public TransactionTestServiceImpl() { };
>  
> public void method(XXXXXX xxxxxx) {
>  
>     S2Container container = S2ContainerFactory.create("XXX/transaction_dao.dicon");
> 
>     TransactionTestDao transactionTestDao = (TransactionTestDao) container.
>             getComponent("TransactionTestDao");
>  
>     transactionTestDao.addSQL1(xxxxxx);
>     transactionTestDao.addSQL2(xxxxxx);
>     transactionTestDao.addSQL3(xxxxxx);
>     
>     // ここでエラーを起こして処理を中断 (スローした例外は“処理の最初に呼ばれるメソッド”でキャッチ)
>     ×××××(エラーを起こすコード)
>     
>     transactionTestDao.addSQL4(xxxxxx);
>     transactionTestDao.addSQL5(xxxxxx);
> }
>>>>           
>  
> 
> 
> ////////// transaction_dao.dicon //////////
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
> <components>
>  
>     <include path="dao.dicon" />
>  
>     <component name="TransactionTestDao" class="XXX.TransactionTestDao">
>         <aspect>dao.interceptor</aspect>
>     </component>
>  
> </components>
>  
>  
>  
>  
> ////////// TransactionTestDao.java //////////
>  
> public interface TransactionTestDao {
>  
>   Class<XXXXXX> BEAN = XXXXXX.class;
>  
>   String addSQL1_SQL_FILE = "XXX/XXX/XXXXX/addSqlOneQuery.sql";
>   String addSQL2_SQL_FILE = "XXX/XXX/XXXXX/addSqlTwoQuery.sql";
>   String addSQL3_SQL_FILE = "XXX/XXX/XXXXX/addSqlThreeQuery.sql";
>   String addSQL4_SQL_FILE = "XXX/XXX/XXXXX/addSqlFourQuery.sql";
>   String addSQL5_SQL_FILE = "XXX/XXX/XXXXX/addSqlFiveQuery.sql";
>  
>   String addSQL1_ARGS = "xxxxxx";
>   String addSQL2_ARGS = "xxxxxx";
>   String addSQL3_ARGS = "xxxxxx";
>   String addSQL4_ARGS = "xxxxxx";
>   String addSQL5_ARGS = "xxxxxx";
>  
>   void addSQL1(XXXXXX xxxxxx);
>   void addSQL2(XXXXXX xxxxxx);
>   void addSQL3(XXXXXX xxxxxx);
>   void addSQL4(XXXXXX xxxxxx);
>   void addSQL5(XXXXXX xxxxxx);
> }
>  
>  
>  
>  
> ////////// app.dicon //////////
>  
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
> <components>
>     <include path="convention.dicon"/>
>     <include path="aop.dicon"/>
>     <include path="j2ee.dicon"/>
> </components>
>  
>  
>  
> 
> 
> ////////// convention.dicon //////////
>  
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
> <components>
>     <component class="org.seasar.framework.convention.impl.NamingConventionImpl">
>         <initMethod name="addRootPackageName">
>             <arg>"org.seasar.framework.container.warmdeploy"</arg>
>         </initMethod>
>     </component>
>     <component class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
> </components>
>  
>  
>  
> 
> 
> ////////// jdbc.dicon //////////
>  
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd">
> <components namespace="jdbc">
>  
>     <include path="jta.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>
>  
>     <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
>         <property name="driverClassName">"org.postgresql.Driver"</property>
>         <property name="URL">"jdbc:postgresql://XXXXXXXXXXXX"</property>
>         <property name="user">"XXXXXXXX"</property>
>         <property name="password">"XXXXXXXX"</property>
>     </component>
>  
>     <component name="connectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
>         <property name="timeout">600</property>
>         <property name="maxPoolSize">10</property>
>         <property name="allowLocalTx">true</property>  <!-- ←★ falseにすると例外をスロー ★ -->
>         <destroyMethod name="close"/>
>     </component>
>  
>     <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
>  
> </components>

--
{
  name: "Koichi Kobayashi",
  mail: "[E-MAIL ADDRESS DELETED]",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
 }



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