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

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2006年 11月 16日 (木) 20:00:20 JST


小林 (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 メーリングリストの案内