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