2011-09-13 5 views
1

私のアプリケーションは、tamcatサーバーとmysql上のconiberian hibernateとspring frameworkです。Spring beans内のトランザクション

私はトランザクショナルとして機能に注釈を付けましたが、私はそれがtransacitonalメソッドとして動作していないことがわかりました(たとえば、関数の終了前にクエリブラウザでDBの変更を見ることができます)。

方法が豆から実行されますが、別のスレッドで、次のように:doDbStuff内部

executor.submit(new Runnable(){ 

     @Override 
     public void run() { 

      someSpringService.doDbStuff(); 
     } 
    }); 

、私はいくつかのメソッドを呼び出していて、それぞれの方法は、このように、テンプレートを使用して:

return getHibernateTemplate().execute(new HibernateCallback(){ 
     public Object doInHibernate(Session session) throws HibernateException, SQLException { 
      return session.createCriteria(MyClass.class).add(Restrictions.eq("id", id)) 
        .uniqueResult(); 
     } 
    }); 

時々、HiberateCallbackネイティブSQLクエリ内で実行され、セッションiをdoInHiberateの引数として使用します。

私の質問は - 1.私は別のスレッドを使用しているため、トランザクションの注釈は無視されますか? 2.トランザクションアノテーションでアノテーションされた関数をSpring Beanとして実行するにはどうすればよいですか(通常の関数としてではなく、おそらく1を解決します)? 3.トランザクションアノテーションを含むコールスタック内に複数のHibernateCallbackを作成すると、トランザクションメソッドとして動作しますか?私は同じセッションを使用する必要がありますし、内部の関数間で渡す?

おかげで...

答えて

1

機能が

を終える前に、私はあなたがいないスレッドの中から、あなたの方法を実行すると、それは異なった動作ん、クエリブラウザでDBの変化を見ることができます?私は別のスレッドを使用していますので、これは

  1. は、トランザクションの注釈が無視される...のMySQL /トランザクション分離問題になる可能性がありますか?

この場合はありません。あるスレッドでトランザクションを作成してから新しいスレッドを作成する場合、後者はトランザクションを「継承」しません。あなたの場合、トランザクションは新しいスレッド内で開始され、正しく動作します。

またdoDbStuff()内でこれを実行してみてください:

TransactionSynchronizationManager.isActualTransactionActive() 

を確認します。

  1. どのように私は(とではない通常の関数として - 多分それは1が解決されます)のSpring Beanとしてトランザクションアノテーションを付けている機能を実行することができますか?

どういう意味ですか? someSpringServiceがSpringによって注入され、doDbStuff()@Transactionalと注釈されたパブリックメソッドである場合、それはうまくいくはずです。しかし、いくつかの問題があります。たとえば、非トランザクションの非公開トランザクションからパブリック・トランザクション・メソッドを呼び出すBeanの内部にいる場合は、動作しない可能性があります。

  1. 私はトランザクションの注釈を含むコールスタック内の複数のHibernateCallbackのを作成する場合は、 - それはトランザクションの方法として振る舞うのですか?私は同じセッションを使用する必要がありますし、内部の関数間で渡す?

HibernateCallback同じJDBC接続を再利用してくれている - >取引 - >セッションを休止。

+0

私はTransactionSynchronizationManager.isActualTransactionActive()を確認しました。私が思ったように、falseを返しました。私は問題は、別のスレッド(トランザクションの注釈付き関数の呼び出しスタックには春のクラスが含まれていない...)から通常の関数としてSpring Beanを実行することです。通常のbeanとしてfuncitonを実行する方法を知っていますか? – yonatan

+0

BTW - hibrtnateTemplate.beginSession()。startTransaction()を使用して関数の最後にコミットしても、内部関数はトランザクションを認識しません。 – yonatan

+0

'someSpringService'をどうやって取得しますか? 'executor.submit()'の前に 'someSpringService.doDbStuff();'を実行してみてください(同じスレッド内)。それはその後動作しますか?もしそうなら、2番目の質問に値する。 –

0

はあなたのapplicationContext.xmlを内

<tx:annotation-driven/> 

を持っていることを確認してください。

+0

@erucacn - 私は持っています – yonatan

関連する問題