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