远程 EJB 调用的事务
Posted
技术标签:
【中文标题】远程 EJB 调用的事务【英文标题】:Transactions on remote EJB calls 【发布时间】:2012-12-24 10:56:50 【问题描述】:我有一个关于 glassfish 中的事务和 CORBA 的奇怪问题。我可以解决问题,但我仍然不知道为什么会发生此错误:
我有两个类,我们称它们为 Client 和 RemoteImpl。 客户端在一台服务器上,远程在另一台服务器上。
客户端看起来像这样(更简单的例子,不是真正的代码):
@Stateless
public class Client
@EJB(name = "TheRemoteEJB")
protected Remote remoteEJB;
@Schedule(hour = "*", minute = "*/5", persistent = false)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void doSomeStuff()
for(int i=0;i<300000;i++)
remoteEJB.theMethodToCall(i);
... other code that may take a bit longer...
RemoteImpl 看起来像这样:
@Stateless
@Remote(RemoteInterface.class)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class RemoteImpl
@EJB
private SomeJPAFacade facade;
@Override
public int theMethodToCall(int param) throws SomeException
Bean products = facade.findBySomeSelect(param);
return bean.getAValue();
其他使用的类有:
SomeException:
public class SomeException extends Exception
public SomeException()
super();
public SomeException(String message)
super(message);
和远程接口
public interface RemoteInterface
public int theMethodToCall() throws SomeException
问题是,当 doSomeStuff 耗时过长时,会引发 CORBA 异常:
[#|2012-12-22T03:10:03.327+0100|INFO|glassfish3.1.2|com.foo.bar.Client|_ThreadID=47;_ThreadName=Thread-2;|javax.ejb.EJBException: javax.transaction.InvalidTransactionException: CORBA INVALID_TRANSACTION 0 No
; nested exception is:
org.omg.CORBA.INVALID_TRANSACTION: vmcid: 0x0 minor code: 0 completed: No
at com.foo.bar.Client._Remote_Wrapper.theMethodToCall(com/foo/bar/_RemoteInterface_Wrapper.java)
at com.foo.bar.Client.doSomeStuff(Client.java:73)
at sun.reflect.GeneratedMethodAccessor3162.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:49)
at sun.reflect.GeneratedMethodAccessor80.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundTimeout(SystemInterceptorProxy.java:149)
at sun.reflect.GeneratedMethodAccessor371.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:4058)
at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1832)
at com.sun.ejb.containers.EJBTimerService.access$100(EJBTimerService.java:108)
at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:2646)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.transaction.InvalidTransactionException: CORBA INVALID_TRANSACTION 0 No; nested exception is:
org.omg.CORBA.INVALID_TRANSACTION: vmcid: 0x0 minor code: 0 completed: No
at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:281)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:213)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:227)
at com.foo.bar.__RemoteInterface_Remote_DynamicStub.matchByParityId(com/foo/bar/__RemoteInterface_Remote_DynamicStub.java)
... 39 more
Caused by: org.omg.CORBA.INVALID_TRANSACTION: vmcid: 0x0 minor code: 0 completed: No
at com.sun.jts.CosTransactions.CurrentTransaction.sendingRequest(CurrentTransaction.java:812)
at com.sun.jts.CosTransactions.SenderReceiver.sending_request(SenderReceiver.java:138)
at com.sun.jts.pi.InterceptorImpl.send_request(InterceptorImpl.java:338)
at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeClientInterceptorStartingPoint(InterceptorInvoker.java:290)
at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeClientPIStartingPoint(PIHandlerImpl.java:376)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(CorbaClientRequestDispatcherImpl.java:304)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.request(CorbaClientDelegateImpl.java:228)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:194)
... 42 more
Caused by: org.omg.CosTransactions.Unavailable: IDL:omg.org/CosTransactions/Unavailable:1.0
at com.sun.jts.CosTransactions.TopCoordinator.get_txcontext(TopCoordinator.java:2787)
at com.sun.jts.CosTransactions.ControlImpl.getTXContext(ControlImpl.java:824)
at com.sun.jts.CosTransactions.CurrentTransaction.sendingRequest(CurrentTransaction.java:804)
... 49 more
|#]
我明确告诉 ApllicationServer @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
,因为我不想跨越事务。但异常看起来像是有交易。我一直认为事务不能跨越对另一个 glassfish 实例的远程调用?
我可以通过删除@TransactionAttribute
并在Client-class 中添加@TransactionManagement(TransactionManagementType.BEAN)
来解决问题。
但我还是想知道为什么会发生这个错误。
感谢您的回复。
更新: 错误报告已归档于:https://java.net/jira/browse/GLASSFISH-17535
【问题讨论】:
【参考方案1】:NOT_SUPPORTED 表示The container invokes an enterprise bean method whose transaction attribute NOT_SUPPORTED with an unspecified transaction context.
似乎是未指定的上下文导致了无效事务异常。
通过使用 bean 管理的事务,您告诉容器不要提供任何事务上下文,因此它可以防止该异常。
这对我来说就像一个错误,我对 glassfish 不是很熟悉,直觉告诉我这应该有效。
【讨论】:
感谢您的回复,我也认为这是一个错误。也许我要提交一份错误报告。以上是关于远程 EJB 调用的事务的主要内容,如果未能解决你的问题,请参考以下文章