[Seasar-user:5162] Re: [S2Dao] 別スレッドトランザクションのデータの読み込み

NAKAMURA Manabu [E-MAIL ADDRESS DELETED]
2006年 11月 16日 (木) 21:12:19 JST


お疲れ様です、中村です。

ちょっと思ったんですが、
org.seasar.extension.jta.TransactionManagerImpl
を以下の様に変更した新しいTransactionManager実装を作成して
j2ee.dicon を置き換えると解決できそうな気がするんですが、
これだと何か問題起きますでしょうか?

---------------------
private ThreadLocal threadAttachTx_ = new ThreadLocal();
  ↓
private ThreadLocal threadAttachTx_ = new InheritableThreadLocal();
---------------------

# threadAttachTx_ が protected であれば TransactionManagerImpl を継承して
# 簡単に実装が作れるんですが……。

> 小林 (koichik) です.
> 
> Date:    Thu, 16 Nov 2006 17:47:45 +0900
> From:    "小林正和" <[E-MAIL ADDRESS DELETED]>
> To:       [E-MAIL ADDRESS DELETED]
> Subject: [Seasar-user:5156] [S2Dao] 別スレッドトランザクションのデータの読み込み
> 
> > java.util.TimerTaskを使用して、データベースにデータを書き込むプログラムをテストしているのですが、
> > テーブルからデータを読み込むことができません。
> > 
> > TimerTaskで実行されるのがテストケースとは別のスレッドのためだとは思うのですが、
> 
> その通りです.
> S2TestCase の場合, 〜Tx() という名前のメソッドは
> 実行前にトランザクションが開始され,終了時にロールバック
> されます.
> このトランザクションはスレッドに関連付けられており,
> テストメソッドの中で更新したデータを他のスレッドから
> 参照することはできません.
> 
> テストメソッドからは Tx を外してください.
> その場合,JDBC コネクションは自動コミットモードに
> なります.
> readXlsWriteDb() で更新した内容を取り消すには
> S2TestCase の deleteTable(String) または deleteDb(DataSet)
> などを使用してください.
> 
> 
> なお,サンプルでは TimerTask 上で DB を読んでいるだけですが,
> 実際には
> 
> > java.util.TimerTaskを使用して、データベースにデータを書き込む
> 
> と,更新系のようですね.
> 現在の TimerTask 実装クラス FooTask ですが,
> 
> > //タスククラス
> > public class FooTask extends TimerTask{
> >   private FooDao fooDao;
> >   public FooTask(FooDao fooDao){
> >     this.fooDao = fooDao;
> >   }
> >   public void run(){
> >     Foo foo = fooDao.get(1);  //←ここで、fooにnullがセットされる。
> >     if(foo == null){
> >       throw new Exception();
> >     }
> >   }
> > }
> 
> ここでの DB アクセスも自動コミットモードに
> なってしまうので,ちょっとした参照系ならともかく,
> 更新系では問題が生じる可能性があると思います.
> 
> できるなら,この FooTask も S2 で管理することにして,
> S2Tx による自動トランザクションを適用しては
> いかがでしょうか.
> それには FooTask を次のように dicon に定義します.
> # 自動登録などを利用してもかまいません.
> 
> <component name="fooTask" class="FooTask">
>   <aspect pointcut="run">j2ee.requiredTx</aspect>
> </component>
> 
> これで run() がトランザクションの元で実行されるように
> なります.
> 
> すると,これを使う BarImpl は
> 
> public class BarImpl implements Bar{
>   private TimerTask fooTask;
>   public void setFooTask(TimerTask fooTask){
>     this.fooTask = fooTask;
>   }
>   public void execute(){
>     Timer timer = new Timer();
>     timer.schedule(task, 1000); //1秒後にFooTaskのrunが実行される。
>   }
> }
> 
> のようになります.
> ご検討ください.
> 
> 
> --
> <signature>
>    <name>Koichi Kobayashi</name>
>    <e-mail>[E-MAIL ADDRESS DELETED]</e-mail>
> </signature>
> 
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user

--------------------------------------
 中村 学/NAKAMURA Manabu
 [E-MAIL ADDRESS DELETED]
--------------------------------------






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