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
WebコンテキストAでトランザクションを開始し、WebコンテキストBでBeanをコールするとどうなりますか?私は、BのトランザクションフックがWebコンテキストAで実行されることを期待しています。 WebコンテクストBで/トランザクションフックを再度実行する方法はありますか? – wdk
トランザクションはスレッドにバインドされていますが、JNDIコンテキストはコンテキスト・コンテキストです。あなたのコミットはEJBの外にあり、あなたはEJBのコンテキストを持っていません。 –