2009-04-30 5 views
1

「scope」が正しい用語であるかどうかは不明です。@Transactionalの範囲を最小限にしたいですか?

私は、JPAトランザクション管理(下のHibernateを使用)にSpringを使用しています。データベーストランザクションをプリフォームへの私の方法はプライベートですが、あなただけのクラスまたはpublic method

に@Transactionalを設定することができるので、このメカニズムは、プロキシ上で、唯一「外部」の方法は、プロキシ経由で着信したコールベースにしているためだろう傍受される。これは、呼び出されたメソッドが@Transactional!でマークされていても、実行時に 'self-invocation'、つまりターゲットオブジェクト内の他のメソッドを呼び出すターゲットオブジェクト内のメソッドは実際のトランザクションにつながりません。

クラスのパブリックエントリポイントを@Transactionalとして設定しました。

@Transactional 
public void run(parameters) { 
    //First non-database method, takes a decent amount of time 
    Data data = getData(); 
    //Call to database 
    storeData(data); 
} 

private storeData(data) { 
    em.persist(data); 
} 

これは悪い習慣ですか? Springはここで必要以上にオープントランザクションを維持していますか?私は、storeData()メソッドをDAOクラスに移動してパブリックにすることを考えていましたが、学問的なポイントとして、リファクタリングが一般に公開されていればパフォーマンス上のメリットがあるかどうかを知りたかったのです。

+0

私はそれらを正しく理解すれば、反対のことを言っているのですが、他の誰かがこの質問にうかがいますか? –

+0

質問にはhttp://stackoverflow.com/questions/1079114が関係しています。 –

答えて

1

DBに多量の競合がある場合、トランザクションをできるだけ小さく保つことは間違いなく重要です。パブリックとプライベートの区別よりも重要であり、パフォーマンスやスケーラビリティには影響しません。そう、実用的な...!

+0

私はあなたが私の質問を誤解しているかもしれないと思います。 @Transactionalはパブリックメソッドのみに存在することができますが、私は、データベース作業のみを行っているメソッドに@Transactionalを制限することをお勧めします。 –

+1

私は理解しました:トランザクションスコープを可能な限り厳密に制限する必要があります。それは、あなたが秘密にしておくことを公開するということを意味する場合、それは世界の終わりではありません。 –

1

トランザクションスコープは、コードがトランザクションコンテキスト(この場合はstoreData()メソッド)とやりとりするまでは無効です。 getData()が非トランザクションであるという事実は、データベースのロックはstoreData()に達したときにのみ起こるため、コードの並行処理のパフォーマンスに影響を与えるべきではありません。

+0

トランザクションの分離レベルに依存します。 SERIALIZABLE分離を使用すると、データベースはトランザクションの開始時に状態を追跡して、他のトランザクションからのコミットが読み取りに影響を与えないようにする必要があります。 – andri

+0

@andri、トランザクションはいつ開始されますか?私はskaffmanがem.persistへの呼び出しまで開始しないと言っていると思った? –

+1

データベースに関する限り、トランザクションはデータベースへの接続が取得されたときにのみ開始されます。 storeData()メソッドが呼び出されるまでこれが行われないと、データベースに関する限り、トランザクションが開始されます。接続が含まれる前に、データベースは関与せず、通知されません。 – skaffman

関連する問題