openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pinaki Poddar (JIRA)" <j...@apache.org>
Subject [jira] Commented: (OPENJPA-462) OptimisticException is thrown instead of OptimisticLockException
Date Thu, 06 Dec 2007 20:45:43 GMT

    [ https://issues.apache.org/jira/browse/OPENJPA-462?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12549180
] 

Pinaki Poddar commented on OPENJPA-462:
---------------------------------------

An optimistic violation often manifests as a SQLException during implicit or explicit flush/commit
operation. 
As this SQL exception bubbles up the stack of OpenJPA layers, the exception gets translated
with the original exception being nested within. 
The OpenJPA facade translates an exception to javax.persistence.OptimisticLockException for
the user application *if* the lower layer 
(i.e. spec-agnostic OpenJPA kernel) raises or translates original SQLException to a org.apache.openjpa.util.OptimisticException.
If the context is not sufficient to translate the exception to  org.apache.openjpa.util.OptimisticException,
it gets translated to 
org.apache.openjpa.util.StoreException which is the generic type from all exceptions raised
by the underlying datastore (which is JDBC datastore in this case).

The attached patch addresses this issue by narrowing down the original SQLException to a specific
subtype of  StoreException based on the SQLState carried by the original SQLException. 
As a result, the JPA-facade layer can translate the exception to a org.apache.opejpa.persistence.OptimisticLockException
which is derived from intended javax.persistence.OptimisticLockException.
But this exception can get nested further up the exception translation chain before it reaches
the user application.

So, if an application wants to detect whether the exception is caused by optimistic consistency
violation, one way to do it is

	boolean isExpectedException(Throwable t, Class expected) {
		if (t == null) return false;
		if (expected.isAssignableFrom(t.getClass()))
				return true;
		if (t.getCause()==t) return false;
		return isExpectedException(t.getCause(), expected);
	}

     and call it from the application code as:

     try {
        // do some JPA stuff;
     } catch (Throwable t) {
           if (isExpectedException(t, javax.persistence.OptimisticLockException.class) {
                // do some smart thing to retry/recover
           else
             // rethrow
    }

Notes on the patch:
  1. The existing DBDictionary.newStoreException() method did detect referential integrity
violations by analyzing java.sql.SQLException.getSQLState(). 
  2. This patch generalizes the same logic to other violations such as locking or duplicate
key.
  3. The only context available to narrow down the cause is  java.sql.SQLException.getSQLState()
-- which is ideally be same across JDBC drivers and different databases. 
But ideals are seldom met. So a new method
                   public String[] DBDictionary.getKnownErrorCodes(int storeExceptionType)

is introduced, that can be overwritten by database-specific DBDictionary derivations.
  4. The patch only supplies two error codes for referential integrity and locking errors.

===============================================================================================
If someone can point me to an enumeration of these (supposedly database-neutral) error codes
returned by 
SQLException.getSQLState() that will be of great help.
===============================================================================================

> OptimisticException is thrown instead of OptimisticLockException
> ----------------------------------------------------------------
>
>                 Key: OPENJPA-462
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-462
>             Project: OpenJPA
>          Issue Type: Bug
>    Affects Versions: 0.9.7
>         Environment: BEA WebLogic Server 10
>            Reporter: Ajay Aggarwal
>
> In my application, i wanted to catch "javax.persistence.OptimisticLockException" and
take appropriate action. However I am seeing that instead "org.apache.openjpa.util.OptimisticException"
is being thrown. I don't want my code to become dependent on OpenJPA and would like to see
OptimisticLockException thrown.
> While discussing in the OpenJPA forums, Patrick suggested that I create a JIRA issue
for this since its a bug.
> You can see the discussion in the forum under title "OptimisticException question" few
days ago.
> Below is the stack trace from my application.
> <Nov 30, 2007 9:50:53 AM EST> <Error> <EJB> <BEA-010026> <Exception
occurred during commit of transaction Name=[EJB com.covergence.soa.covapi.sesscfg.SessionConfigBean.getSessionConfig(com.covergence.soa.utils.SerJavaSipMessageType)],Xid=BEA1-00001267875BE126CEB7(64273527),Status=Rolled
back. [Reason=<2|false|0.9.7> org.apache.openjpa.util.OptimisticException: Optimistic
locking errors were detected when flushing to the data store.  The following objects may have
been concurrently modified in another transaction: [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds
since begin=2,seconds left=30,SCInfo[ajayProduction+AdminServer]=(state=rolledback),properties=({weblogic.transaction.name=[EJB
com.covergence.soa.covapi.sesscfg.SessionConfigBean.getSessionConfig(com.covergence.soa.utils.SerJavaSipMessageType)]}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=AdminServer+172.30.0.202:7001+ajayProduction+t3+admin+7001+,XAResources={WLStore_ajayProduction__WLS_AdminServer},NonXAResources={})],CoordinatorURL=AdminServer+172.30.0.202:7001+ajayProduction+t3+admin+7001+):
weblogic.transaction.RollbackException: Optimistic locking errors were detected when flushing
to the data store.  The following objects may have been concurrently modified in another transaction:
[com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
>         at weblogic.transaction.internal.TransactionImpl.throwRollbackException(TransactionImpl.java:1818)
>         at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:333)
>         at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
>         at weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
>         at com.covergence.soa.covapi.sesscfg.SessionConfigBean_4w7egw_SessionConfigImpl.getSessionConfig(SessionConfigBean_4w7egw_SessionConfigImpl.java:76)
>         at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
Source)
>         at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
Source)
>         at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:63)
>         at $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
Source)
>         at com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
>         at com.covergence.soa.ws.server.CallOutsImplBase.getSessionPolicy(CallOutsImplBase.java:238)
>         at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
Source)
>         at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
Source)
>         at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:50)
>         at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:42)
>         at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:247)
>         at com.sun.xml.ws.server.sei.SEIInvokerPipe.process(SEIInvokerPipe.java:97)
>         at weblogic.wsee.jaxws.MonitoringPipe.process(MonitoringPipe.java:98)
>         at com.sun.xml.ws.protocol.soap.ServerMUPipe.process(ServerMUPipe.java:62)
>         at com.sun.xml.ws.server.WSEndpointImpl$1.process(WSEndpointImpl.java:139)
>         at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:153)
>         at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:235)
>         at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:97)
>         at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:36)
> .>
> javax.ejb.EJBException: nested exception is: <2|false|0.9.7> org.apache.openjpa.util.OptimisticException:
Optimistic locking errors were detected when flushing
> to the data store.  The following objects may have been concurrently modified in another
transaction: [com.covergence.soa.covapi.userpolicy.User-com.covergence.
> soa.covapi.userpolicy.User-1]<2|false|0.9.7> org.apache.openjpa.util.OptimisticException:
Optimistic locking errors were detected when flushing to the data store.  The following objects
may have been concurrently modified in another transaction: [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
>         at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2120)
>         at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1970)
>         at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1868)
>         at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1786)
>         at weblogic.transaction.internal.ServerSCInfo.doBeforeCompletion(ServerSCInfo.java:1212)
>         at weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(ServerSCInfo.java:1190)
>         at weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(ServerSCInfo.java:118)
>         at weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain(ServerTransactionImpl.java:1299)
>         at weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare(ServerTransactionImpl.java:2111)
>         at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:260)
>         at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
>         at weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
>         at com.covergence.soa.covapi.sesscfg.SessionConfigBean_4w7egw_SessionConfigImpl.getSessionConfig(SessionConfigBean_4w7egw_SessionConfigImpl.java:76)
>         at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
Source)
>         at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
Source)
>         at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:63)
>         at $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
Source)
>         at com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
> Caused by: <2|false|0.9.7> org.apache.openjpa.util.OptimisticException: An optimistic
lock violation was detected when flushing object instance "com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1"
to the data store.  This indicates that the object was concurrently modified in anothertransaction.
> FailedObject: com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1
>         at kodo.jdbc.kernel.BatchingPreparedStatementManager.checkUpdate(BatchingPreparedStatementManager.java:354)
>         at kodo.jdbc.kernel.BatchingPreparedStatementManager.flushInternal(BatchingPreparedStatementManager.java:208)
>         at kodo.jdbc.kernel.BatchingPreparedStatementManager.flush(BatchingPreparedStatementManager.java:188)
>         at kodo.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:90)
>         at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:86)
>         at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:69)
>         at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:511)
>         at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:127)
>         at org.apache.openjpa.datacache.DataCacheStoreManager.flush(DataCacheStoreManager.java:506)
>         at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:127)
>         at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1970)
>         at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1868)
>         at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1786)
>         at weblogic.transaction.internal.ServerSCInfo.doBeforeCompletion(ServerSCInfo.java:1212)
>         at weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(ServerSCInfo.java:1190)
>         at weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(ServerSCInfo.java:118)
>         at weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain(ServerTransactionImpl.java:1299)
>         at weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare(ServerTransactionImpl.java:2111)
>         at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:260)
>         at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:227)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvoke1(BaseRemoteObject.java:606)
>         at weblogic.ejb.container.internal.StatelessRemoteObject.postInvoke1(StatelessRemoteObject.java:57)
>         at weblogic.ejb.container.internal.BaseRemoteObject.postInvokeTxRetry(BaseRemoteObject.java:426)
> javax.ejb.EJBException: nested exception is: <2|false|0.9.7> org.apache.openjpa.util.OptimisticException:
Optimistic locking errors were detected when flushing to the data store.  The following objects
may have been concurrently modified in another transaction: [com.covergence.soa.covapi.userpolicy.User-com.covergence.soa.covapi.userpolicy.User-1]
>         at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:78)
>         at $Proxy67.getSessionConfig(Lcom.covergence.soa.utils.SerJavaSipMessageType;)Lcom.covergence.ws.callouts.SessionConfigType;(Unknown
Source)
>         at com.covergence.soa.ws.server.CallOutsImpl.getSessionConfigType(CallOutsImpl.java:46)
>         at com.covergence.soa.ws.server.CallOutsImplBase.getSessionPolicy(CallOutsImplBase.java:238)
>         at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown
Source)
>         at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown
Source)
>         at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:50)
>         at weblogic.wsee.jaxws.WLSInvoker.invoke(WLSInvoker.java:42)
>         at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:247)
>         at com.sun.xml.ws.server.sei.SEIInvokerPipe.process(SEIInvokerPipe.java:97)
>         at weblogic.wsee.jaxws.MonitoringPipe.process(MonitoringPipe.java:98)
>         at com.sun.xml.ws.protocol.soap.ServerMUPipe.process(ServerMUPipe.java:62)
>         at com.sun.xml.ws.server.WSEndpointImpl$1.process(WSEndpointImpl.java:139)
>         at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:153)
>         at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:235)
>         at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:97)
>         at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:36)
>         at weblogic.wsee.jaxws.JAXWSServlet.doPost(JAXWSServlet.java:218)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:226)
>         at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:124)
>         at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
>         at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
>         at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3370)
>         at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
>         at weblogic.security.service.SecurityManager.runAs(Lweblogic.security.acl.internal.AuthenticatedSubject;Lweblogic.security.acl.internal.AuthenticatedSubject;Ljava.security.PrivilegedAction;)Ljava.lang.Object;(Unknown
Source)
>         at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2117)
>         at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2023)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message