2017-06-24 29 views
0

このコードはJava EE仕様と共通で使用できますか?Java EE EJBを実行可能な実行プログラムとして

@Stateless 
public class SomeBean { 

    @Inject 
    protected TransactedRunner txRunner; 


    public void someFunc() { 

     txRuner.run(new Runnable(){ 
      Connection c = ds.getConnection(); 
      //do jdbc stuff or jpa stuff 
      //close everything etc. 
     }); 
    } 
} 

@Stateless 
public class TransactedRunner { 

    @TransactionAttribute(REQUIRES_NEW) 
    public void run(Runnable r) { 
     r.run(); 
    } 
} 

この場合、新しいトランザクションを開始する必要があり、実行可能で実行されるすべてのトランザクションが処理されます。そうですか?それとも、私はEEに苦しむべきであるいくつかのトリックがありますか?

答えて

0

意図したとおりこれは動作するはずです。しかし、あるサービスコール中にtxRunner.runを複数回呼び出すと、接続タイムアウト、トランザクションタイムアウト、ノードが死んでしまうなど、これらの呼び出しの間または間に何かが発生すると、データが不一致になる可能性があることに注意してください。呼び出しトランザクション(存在する場合)は、呼び出し中に行われた変更が自身がコミットされるまで表示されないことがあります。

0

JavaEE6には@Asynchronousという名前のアノテーションがありますが、これは特にこの目的のためです。 http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

@Stateless 
public class SomeBean { 

    @Inject 
    private SomeBean self; 

    public void someFunc() { 
     self.doSomething(); 
    } 

    @TransactionAttribute(REQUIRES_NEW) 
    @Asynchronous 
    private void doSomething() { 
     Connection c = ds.getConnection(); 
     //do jdbc stuff or jpa stuff 
     //close everything etc. 
    } 
} 

また、EJBコンテナ内のスレッドを作成したり、管理することが許可されていません。ここでは公式のチュートリアルです。チェックアウト:http://www.oracle.com/technetwork/java/restrictions-142267.html#threads

なぜスレッドの作成と管理が許可されていないのですか?

EJB仕様は、スレッドを管理する責任をEJBコンテナに割り当てます。エンタープライズBeanインスタンスがスレッドを作成して管理できるようにすると、コンポーネントのライフサイクルを制御するコンテナの機能が妨げられます。スレッド管理はビジネス機能ではなく、実装の詳細であり、通常は複雑でプラットフォーム固有です。コンテナがスレッドを管理するようにすると、エンタープライズBeanの開発者はスレッドの問題に対処できます。マルチスレッド・アプリケーションは引き続き可能ですが、マルチスレッドの制御は、エンタープライズBeanではなくコンテナ内にあります。

+0

私はスレッドを作成しません。 runメソッドを使ってEJBを呼び出します。私は非同期実行も必要ありません。ポイントは、実行可能なコードのトランザクションブロックを達成することです。 – fantomasdnb

+0

私はスレッドを使わずにRunnable Interfaceを使用しません。 Runnableインタフェースは、インスタンスがスレッドによって実行されることを意図しているすべてのクラスによって実装される必要があります。 –

+0

Runnableは単なるインタフェースです。たとえば、EclipseのSWT/JfaceフレームワークRunnableは、lambdaのようなコードブロックを渡すために使用されます。また、EJBでそれを渡すことは、ejbがそのコードを内部で受け取る魔法のようなものではありません。また、リモートejbでない場合は、同じスレッドになります。私はかなり確信していますが、私は確かにイエスかノーですか)。ありがとう。 – fantomasdnb

0

メソッド "run"はトランザクションで実行されますが、それは本当です。しかし、それはスレッド化またはエグゼキュータを使用することと共通していません。あなたの例では、呼び出しスレッドは "run"メソッドを実行します。 Runnableインターフェイス自体はあなたのために別のスレッドを作成しません。

あなたが別のスレッドで実行されるように、この呼び出しが必要な場合は、EE7から始まる、非同期呼び出しを使用するか、またはすることができ、ManagedExecutorServiceが利用可能です:

http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html

関連する問題