2017-11-29 13 views
0

TomEEでは、ejbがトランザクション同期レジストリに同期を登録しているときに、beforeCompletionにejbコンテキストがありません。 Bean javax.ejb.BeforeCompletionを使用する場合、そこに存在します。 jee/ejbの仕様にしたがって、どのようなことが予想されますか?javax.transaction.Synchronization.beforeCompletionとjavax.ejb.BeforeCompletionのEJBコンテキスト

testWithWrappedUserTransactionが失敗しているコードのテストケースの下を参照してください:

import java.util.Properties; 
import java.util.concurrent.Callable; 

import javax.annotation.Resource; 
import javax.ejb.AfterBegin; 
import javax.ejb.AfterCompletion; 
import javax.ejb.BeforeCompletion; 
import javax.ejb.EJB; 
import javax.ejb.EJBException; 
import javax.ejb.Stateful; 
import javax.ejb.embeddable.EJBContainer; 
import javax.enterprise.context.RequestScoped; 
import javax.transaction.Synchronization; 
import javax.transaction.TransactionSynchronizationRegistry; 
import javax.transaction.UserTransaction; 

import org.apache.openejb.core.ThreadContext; 

import junit.framework.TestCase; 

public class TransactionTest extends TestCase 
{ 
@Resource 
private TransactionSynchronizationRegistry registry; 

@Resource 
private UserTransaction transaction; 
@EJB 
private Caller transactionalCaller; 

@EJB 
private Caller transactionalCaller2; 

@Override 
protected void setUp() throws Exception { 
    final Properties p = new Properties(); 
    p.put("movieDatabase", "new://Resource?type=DataSource"); 
    p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver"); 
    p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); 

    EJBContainer.createEJBContainer(p).getContext().bind("inject", this); 
} 

private void doWork() throws Exception { 
    registry.registerInterposedSynchronization(new SynchronizationImplementation()); 
} 

class SynchronizationImplementation implements Synchronization 
{ 
    @Override 
    public void beforeCompletion() { 
     System.out.println("XXX: beforeCommit"); 
     assertEJBContext(); 
    } 

    @Override 
    public void afterCompletion(int paramInt) { 
     System.out.println("XXX: afterCommit"); 
     assertEJBContext(); 
    } 
} 

private static void assertEJBContext() { 
    assertTrue(ThreadContext.getThreadContext() != null); 
} 

public void testWithWrappedUserTransaction() throws Exception { 
    transaction.begin(); 
    try { 
     transactionalCaller.call(() -> { 
      doWork(); 
      return null; 
     }); 
    } finally { 
     transaction.commit(); 
    } 
} 

public void testWithDoubleBeanTransaction() throws Exception { 
    transactionalCaller.call(() -> { 
     doWork2(); 
     return null; 
    }); 
} 

private void doWork2() throws Exception { 
    System.out.println("XXX: doWork2"); 
    transactionalCaller2.call(() -> { 
     doWork(); 
     return null; 
    }); 
} 

public void testWithTransaction() throws Exception { 
    transactionalCaller.call(() -> { 
     doWork(); 
     return null; 
    }); 
} 

public static interface Caller 
{ 
    public <V> V call(Callable<V> callable) throws Exception; 
} 

}

PS:私はTomEEのチケットを記録したが何の応答を得なかっ:https://issues.apache.org/jira/browse/TOMEE-2135

答えて

1

あなたはそれがフック以来存在すると仮定カントejb呼び出しの後に実行される可能性があります.EJBContextの外側にある可能性があります。また、UTを使用すると、EJBコンテナではなく、あなたの責任の下にあります。

+0

WebコンテキストAでトランザクションを開始し、WebコンテキストBでBeanをコールするとどうなりますか?私は、BのトランザクションフックがWebコンテキストAで実行されることを期待しています。 WebコンテクストBで/トランザクションフックを再度実行する方法はありますか? – wdk

+0

トランザクションはスレッドにバインドされていますが、JNDIコンテキストはコンテキスト・コンテキストです。あなたのコミットはEJBの外にあり、あなたはEJBのコンテキストを持っていません。 –

関連する問題