Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-3149

SpringJtaSynchronizationAdapter setRollbackOnly hides causing exception within Weblogic 8.1

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.8, 2.0.2
    • Fix Version/s: 1.2.9, 2.0.3
    • Component/s: Data
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      In previous releases, Spring was swallowing Hibernate exceptions within the TransactionSynchronization beforeCompletion method. For more detail see the following link:

      http://opensource.atlassian.com/projects/spring/browse/SPR-2270

      As the JIRA issue states, the issue was addressed by letting the runtime exception through, but still calling setRollbackOnly.

      The issue is that with this fix within Weblogic 8.1, even though Spring lets the exception propogate up, Weblogic will always output a vague AppSetRollbackOnlyException cause whenever setRollbackOnly is invoked. Hence, the underlying exception is still hidden from the developer.

      We applied the Spring 2.X fix to our version of Spring 1.2.5.

      public void beforeCompletion() {
      try

      { boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); this.springSessionSynchronization.beforeCommit(readOnly); }

      catch (RuntimeException ex)

      { setRollbackOnlyIfPossible(); throw ex; }

      catch (Error err)

      { setRollbackOnlyIfPossible(); throw err; }

      finally

      { // Unbind the SessionHolder from the thread early, to avoid issues // with strict JTA implementations that issue warnings when doing JDBC // operations after transaction completion (e.g. Connection.getWarnings). this.beforeCompletionCalled = true; this.springSessionSynchronization.beforeCompletion(); }

      }

      Notice the code above calls setRollbackOnly and rethrows the exception. With this in place, however, we get the following vague exception from Weblogic:

      <Feb 8, 2007 11:51:08 AM EST> <Info> <EJB> <BEA-010051> <EJB Exception occurred during invocation from home: [email protected] threw exception: javax.ejb.TransactionRolledbackLocalException: Error
      committing transaction:; nested exception is: weblogic.transaction.internal.AppSetRollbackOnlyException
      javax.ejb.TransactionRolledbackLocalException: Error committing transaction:; nested exception is: weblogic.transaction.internal.AppSetRollb
      ackOnlyException
      weblogic.transaction.internal.AppSetRollbackOnlyException
      at weblogic.transaction.internal.TransactionImpl.setRollbackOnly()V(TransactionImpl.java:504)
      at weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly()V(TransactionManagerImpl.java:337)
      at weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly()V(TransactionManagerImpl.java:331)
      at org.springframework.transaction.jta.UserTransactionAdapter.setRollbackOnly()V(UserTransactionAdapter.java:86)
      at org.springframework.orm.hibernate3.SessionFactoryUtils$JtaSessionSynchronization.setRollbackOnlyIfPossible()V(SessionFactoryUtils
      .java:1030)
      at org.springframework.orm.hibernate3.SessionFactoryUtils$JtaSessionSynchronization.beforeCompletion()V(SessionFactoryUtils.java:100
      8)
      at weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(Lweblogic.transaction.internal.TransactionImpl;)V(ServerSCInfo.j
      ava:1010)
      at weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(Lweblogic.transaction.internal.ServerTransactionImpl;I)V(Serve
      rSCInfo.java:115)
      at weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain()V(ServerTransactionImpl.java:1216)
      at weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare()V(ServerTransactionImpl.java:1990)
      at weblogic.transaction.internal.ServerTransactionImpl.internalCommit()V(ServerTransactionImpl.java:275)
      at weblogic.transaction.internal.ServerTransactionImpl.commit()V(ServerTransactionImpl.java:246)
      at weblogic.ejb20.internal.BaseEJBLocalObject.postInvoke(Lweblogic.ejb20.internal.InvocationWrapper;Ljava.lang.Throwable;)V(BaseEJBL
      ocalObject.java:363)
      at
      ...
      ...

      We changed the previous patch to not call setRollbackOnly and allow the exception to propogate:

      public void beforeCompletion() {
      try

      { boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); this.springSessionSynchronization.beforeCommit(readOnly); }

      finally

      { this.beforeCompletionCalled = true; this.springSessionSynchronization.beforeCompletion(); }

      }

      We now get the underlying exception within our stack trace:

      <Feb 8, 2007 12:03:19 PM EST> <Info> <EJB> <BEA-010051> <EJB Exception occurred during invocation from home: [email protected] threw exception: javax.ejb.TransactionRolledbackLocalException: Error
      committing transaction:; nested exception is: org.springframework.jdbc.UncategorizedSQLException: Hibernate transaction synchronization; un
      categorized SQLException for SQL [insert into MYTABLE (COLUMN1, COLUMN2, COLUMN3, COLUMN4) values (?, ?, ?, ?)]; SQL state [40001]; error code [-911]; DB2 SQL error: SQLCODE: -911, SQLSTATE: 40001, SQLERRMC: 2; nested exce
      ption is com.ibm.db2.jcc.a.SqlException: DB2 SQL error: SQLCODE: -911, SQLSTATE: 40001, SQLERRMC: 2
      javax.ejb.TransactionRolledbackLocalException: Error committing transaction:; nested exception is: org.springframework.jdbc.UncategorizedSQL
      Exception: Hibernate transaction synchronization; uncategorized SQLException for SQL [insert into MYTABLE (COLUMN1, COLUMN2, COLUMN3, COLUMN4) values (?, ?, ?, ?)]; SQL state [40001]; error code [-911]; DB2 SQL error: SQLC
      ODE: -911, SQLSTATE: 40001, SQLERRMC: 2; nested exception is com.ibm.db2.jcc.a.SqlException: DB2 SQL error: SQLCODE: -911, SQLSTATE: 40001,
      SQLERRMC: 2
      org.springframework.jdbc.UncategorizedSQLException: Hibernate transaction synchronization; uncategorized SQLException for SQL [insert into MYTABLE (COLUMN1, COLUMN2, COLUMN3, COLUMN4) values (?, ?, ?, ?)]; SQL state [40001
      ]; error code [-911]; DB2 SQL error: SQLCODE: -911, SQLSTATE: 40001, SQLERRMC: 2; nested exception is com.ibm.db2.jcc.a.SqlException: DB2 SQ
      L error: SQLCODE: -911, SQLSTATE: 40001, SQLERRMC: 2
      com.ibm.db2.jcc.a.SqlException: DB2 SQL error: SQLCODE: -911, SQLSTATE: 40001, SQLERRMC: 2
      at com.ibm.db2.jcc.a.cq.e(Lcom.ibm.db2.jcc.a.da;)I(cq.java:1482)
      at com.ibm.db2.jcc.c.bc.s(Lcom.ibm.db2.jcc.a.ct;)V(bc.java:721)
      at com.ibm.db2.jcc.c.bc.k(Lcom.ibm.db2.jcc.a.ct;)V(bc.java:375)
      at com.ibm.db2.jcc.c.bc.a(Lcom.ibm.db2.jcc.a.cg;)V(bc.java:63)
      at com.ibm.db2.jcc.c.q.a(Lcom.ibm.db2.jcc.a.cg;)V(q.java:64)
      at com.ibm.db2.jcc.c.bp.c()V(bp.java:266)
      at com.ibm.db2.jcc.a.cr.V()V(cr.java:1412)
      at com.ibm.db2.jcc.a.cr.d(IZ)V(cr.java:1939)
      at com.ibm.db2.jcc.a.cr.R()I(cr.java:440)
      at com.ibm.db2.jcc.a.cr.executeUpdate()I(cr.java:423)
      at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate()I(PreparedStatement.java:147)
      at org.hibernate.persister.entity.BasicEntityPersister.insert(Ljava.io.Serializable;[Ljava.lang.Object;[ZILjava.lang.String;Ljava.la
      ng.Object;Lorg.hibernate.engine.SessionImplementor;)V(BasicEntityPersister.java:1856)
      at org.hibernate.persister.entity.BasicEntityPersister.insert(Ljava.io.Serializable;[Ljava.lang.Object;Ljava.lang.Object;Lorg.hibern
      ate.engine.SessionImplementor;)V(BasicEntityPersister.java:2200)
      at org.hibernate.action.EntityInsertAction.execute()V(EntityInsertAction.java:46)
      at org.hibernate.engine.ActionQueue.execute(Lorg.hibernate.action.Executable;)V(ActionQueue.java:239)
      at org.hibernate.engine.ActionQueue.executeActions(Ljava.util.List;)V(ActionQueue.java:223)
      at org.hibernate.engine.ActionQueue.executeActions()V(ActionQueue.java:136)
      at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(Lorg.hibernate.engine.SessionImplementor;)V(AbstractFlush
      ingEventListener.java:274)
      at org.hibernate.event.def.DefaultFlushEventListener.onFlush(Lorg.hibernate.event.FlushEvent;)V(DefaultFlushEventListener.java:27)
      at org.hibernate.impl.SessionImpl.flush()V(SessionImpl.java:730)
      at org.springframework.orm.hibernate3.SessionFactoryUtils$SpringSessionSynchronization.beforeCommit(Z)V(SessionFactoryUtils.java:881
      )
      at org.springframework.orm.hibernate3.SessionFactoryUtils$JtaSessionSynchronization.beforeCompletion()V(SessionFactoryUtils.java:100
      5)
      at weblogic.transaction.internal.ServerSCInfo.callBeforeCompletions(Lweblogic.transaction.internal.TransactionImpl;)V(ServerSCInfo.j
      ava:1010)
      at weblogic.transaction.internal.ServerSCInfo.startPrePrepareAndChain(Lweblogic.transaction.internal.ServerTransactionImpl;I)V(Serve
      rSCInfo.java:115)
      at weblogic.transaction.internal.ServerTransactionImpl.localPrePrepareAndChain()V(ServerTransactionImpl.java:1216)
      at weblogic.transaction.internal.ServerTransactionImpl.globalPrePrepare()V(ServerTransactionImpl.java:1990)
      at weblogic.transaction.internal.ServerTransactionImpl.internalCommit()V(ServerTransactionImpl.java:275)
      at weblogic.transaction.internal.ServerTransactionImpl.commit()V(ServerTransactionImpl.java:246)
      at weblogic.ejb20.internal.BaseEJBLocalObject.postInvoke(Lweblogic.ejb20.internal.InvocationWrapper;Ljava.lang.Throwable;)V(BaseEJBL
      ocalObject.java:363)
      ...
      ...

      I know the JTA 1.0.1 specification does not define the behaviour for exceptions thrown from before completion and this is why spring included the call to setRollbackOnly in addition to rethrowing the exception. The issue is that calling setRollbackOnly yields undesirable exception masking within Weblogic 8.1 even if the exception is rethrown. Since we cannot predict the behaviour of every JTA 1.0.1 container, I think this functionality should be configurable. The problem is that SessionFactoryUtils instanciates the SpringJtaSynchronizationAdapter within a static method making the transaction synchronization behaviour not very customizable.

      Thx.

      -karl

        Attachments

          Activity

            People

            Assignee:
            juergen.hoeller Juergen Hoeller
            Reporter:
            kbaum Karl Baum
            Last updater:
            Spring Issues Spring Issues
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Days since last comment:
              3 years, 24 weeks, 4 days ago