为什么我得到EJBTransactionRolledbackException而不是OptimisticLockException?

时间:2018-02-04 09:36:00

标签: jpa jboss

我使用Wildfly和OpenJPA。我有乐观锁定异常的情况。

我得到的错误信息是:

  

00:08:29,373 警告 [com.arjuna.ats.arjuna](默认任务-39)   ARJUNA012125:TwoPhaseCoordinator.beforeCompletion - 失败了   SynchronizationImple< 0:ffffc0a82f91:-3d767137:5a736fa1:D7C,   org.jboss.as.txn.service.internal.tsr.JCAOrderedLastSynchronizationList@244256b9

     
    

:org.apache.openjpa.persistence。 OptimisticLockException :乐观     刷新到数据存储时检测到锁定错误。该     以下对象可能已在另一个对象中同时修改     交易:[com.earnix.eo.entities.optimizer.PricingMixEntity-30400]     ....

  
     

00:08:29,381 错误 [org.jboss.as.ejb3.invocation](默认任务-39)   WFLYEJB0034:组件PricingRuleAccessor上的EJB调用失败   for public public abstract java.util.List   com.earnix.eo.sessions.navigator.PricingRuleAccessor.releasePricingMix(INT,INT)   投   com.earnix.utils.EOException,com.earnix.eo.sessions.utils.EODeadlockException,java.rmi.RemoteException异常:   javax.ejb。 EJBTransactionRolledbackException :事务已回滚       at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:137)       at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:117)       at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:279)       在org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:327)       at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.as.ejb3.remote.EJBRemoteTransactionPropagatingInterceptor.processInvocation(EJBRemoteTransactionPropagatingInterceptor.java:79)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:47)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.deployment.processors.StartupAwaitInterceptor.processInvocation(StartupAwaitInterceptor.java:22)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory $ 1.processInvocation(ShutDownInterceptorFactory.java:64)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.deployment.processors.EjbSuspendInterceptor.processInvocation(EjbSuspendInterceptor.java:53)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:67)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ejb3.component.interceptors.EjbExceptionTransformingInterceptorFactories $ 1.processInvocation(EjbExceptionTransformingInterceptorFactories.java:75)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)       在org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:636)       在org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:356)       at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340)       在org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)       at org.jboss.as.ee.component.ViewService $ View.invoke(ViewService.java:198)       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler.invokeMethod(MethodInvocationMessageHandler.java:328)       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler.access $ 100(MethodInvocationMessageHandler.java:67)       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler $ 1.run(MethodInvocationMessageHandler.java:201)       at org.jboss.as.ejb3.remote.protocol.versionone.MethodInvocationMessageHandler.processMessage(MethodInvocationMessageHandler.java:263)       at org.jboss.as.ejb3.remote.protocol.versionone.VersionOneProtocolChannelReceiver.processMessage(VersionOneProtocolChannelReceiver.java:213)       at org.jboss.as.ejb3.remote.protocol.versiontwo.VersionTwoProtocolChannelReceiver.processMessage(VersionTwoProtocolChannelReceiver.java:76)       at org.jboss.as.ejb3.remote.protocol.versionone.VersionOneProtocolChannelReceiver.handleMessage(VersionOneProtocolChannelReceiver.java:159)       在org.jboss.remoting3.remote.RemoteConnectionChannel $ 5.run(RemoteConnectionChannel.java:456)       在org.jboss.remoting3.EndpointImpl $ TrackingExecutor $ 1.run(EndpointImpl.java:731)       在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)       在java.lang.Thread.run(Thread.java:748)   引起:javax.transaction.RollbackException:ARJUNA016053:无法提交事务。       at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1212)       在com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126)       在com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:89)       at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:91)       ......还有47个   引起:org.apache.openjpa.persistence.OptimisticLockException:刷新到数据存储时检测到乐观锁定错误。以下对象可能已在另一个事务中同时修改:[com.earnix.eo.entities.optimizer.PricingMixEntity-30400]       at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2357)       在org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2205)       在org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2103)       在org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:2021)       at org.jboss.as.txn.service.internal.tsr.JCAOrderedLastSynchronizationList.beforeCompletion(JCAOrderedLastSynchronizationList.java:116)       在com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)       在com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:368)       在com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:91)       在com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)       在com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1200)       ......还有50个   引起:org.apache.openjpa.persistence.OptimisticLockException:在刷新对象实例" com.earnix.eo.entities.optimizer.PricingMixEntity-30400"时检测到乐观锁违规。到数据存储。这表示该对象在另一个事务中同时被修改。   FailedObject:com.earnix.eo.entities.optimizer.PricingMixEntity-30400       at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:124)       at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.batchOrExecuteRow(BatchingPreparedStatementManagerImpl.java:100)       在org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:83)       at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:100)       在org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:88)       在org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550)       在org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:107)       at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59)       在org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:104)       在org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:77)       在org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:731)       在org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131)

我的问题是抛出EJBTransactionRolledbackException而不是OptimisticLockException。因此,我的代码不会将异常视为OptimisticLockException。你知道我怎么能让Wildfly / JPA抛出EJBTransactionRolledbackException吗?

我也看了一下'原因' TransactionRolledbackException的字段,我看到null。 enter image description here

一些代码:

@Override
    public List<PricingMixHeader> releasePricingRule(PricingMixHeader header) throws EOException {
        for (int i = 0; ; i++) {
            try {
                return pricingRuleAccessor.releasePricingMix(header.getPk(), getSessionPk());
            } catch (RemoteException e) {
                DeadlockUtils.handleRemoteException(e, i);
            } catch (EODeadlockException e) {
                // recover from the deadlock
                DeadlockUtils.recover(i, e.getOriginalExceptionStack());
            }
        }
    }

这是客户端的代码。 pricingRuleAccessor.releasePricingMix(...)是对服务器端方法的远程调用调用。在服务器端发生了乐观锁定异常,然后捕获了RemoteException(TransactionRolledbackException继承自RemoteException)。

2 个答案:

答案 0 :(得分:2)

我会建议两件事:

1)您可以在&#39; OptimisticLockException &#39;之前调用em.flush()。发生异常,获取此异常,然后根据需要抛出它。

2)其他可能性是忽略 OptimisticLockException 的详细信息,并创建新的&#39; MyRemoteException &#39; (一个扩展EJBException的ApplicationException)。它就是这样的:

@ApplicationException(rollback = true)
public class MyRemoteException extends EJBException {
  ...
}

抛出此异常,以便您的“查看图层”抓住然后它将决定显示哪些信息。

答案 1 :(得分:0)

当抛出的异常是导致回滚的RuntimeException时,JBoss总是在EJBTransactionRollbackException中包装抛出的异常(在你的情况下为OptimisticLockException)。

在客户端代码中,您必须检查EJBTransactionRollbackException,然后检查原因是否为OptimisticLockException:

try {
...
} catch (EJBTransactionRollbackException e) {
    if (e.getCause() instanceof OptimisticLockException) {
       ...
    }
}