Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpringJtaSynchronizationAdapter setRollbackOnly hides causing exception within Weblogic 8.1 [SPR-3149] #7835

Closed
spring-projects-issues opened this issue Feb 11, 2007 · 14 comments
Assignees
Labels
in: data status: backported type: enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Feb 11, 2007

Karl Baum opened SPR-3149 and commented

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: com.mycompany.MyRemoteEJB_inpik2_HomeImpl@bdfdb4 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: om.mycompany.MyRemoteEJB_inpik2_HomeImpl@acc47a 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


Affects: 1.2.8, 2.0.2

Backported to: 1.2.9

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 13, 2007

Juergen Hoeller commented

Thanks for raising this again, Karl; unfortunately I missed your original comment in that other issue.

I've decided to take a pragmatic route here: SpringJtaSynchronizationAdapter simply does not explicitly call "setRollbackOnly" on WebLogic, detecting WebLogic through the JTA transaction handle having a "weblogic." class name. We could extend this with further providers, once we know that they prefer to handle a beforeCompletion exception directly. And as of Java EE 5's JTA 1.1 (or even all common J2EE 1.4 servers, to the best of my knowledge), we can simply always propagate a beforeCompletion exception without worrying, deprecating the overloaded SpringJtaSynchronizationAdapter constructors completely.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 13, 2007

Juergen Hoeller commented

This should be available in tonight's 2.0.3 snapshot! Please give it an early try and let me know whether it works for you, if you have the chance...

So are you still on Spring 1.2.x? I'm considering a last-minute backport of this stuff to Spring 1.2.9... let me know if that would be relevant to you.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 14, 2007

Karl Baum commented

Juergen, thanks for your quick response on this. Although we would like to upgarde to Spring 2.X, we are currently still at Spring 1.2.5. When there is enough need, we will eventually upgrade to 2.X, but as of now 1.2.9 is a more realistic. That being said, I can test this fix using Spring 2.X, but it would be even easier for me to test using Spring 1.2.9 given that there are some minor incompatibility issues for our app with Spring 2.X.

Thanks again for your help!

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 14, 2007

Juergen Hoeller commented

OK, I've backported the entire new beforeCompletion to 1.2.9: propagating exceptions, avoiding setRollbackOnly on WebLogic. I'll publish a 1.2.9-20070215 snapshot tomorrow morning (in about 12 hours); it would be great if you could give that one a try once it is available!

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 14, 2007

Juergen Hoeller commented

FYI, the 1.2.9-20070215 snapshot, including this fix, is now available from http://static.springframework.org/downloads/nightly/

It would be great if you could give it a try and let me know whether it works for you! Should be a drop-in replacement for 1.2.5...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 14, 2007

Karl Baum commented

Great! I'll give it a try as soon as I can. Thanks again!

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 15, 2007

Karl Baum commented

Hi Juergen. I tested the 1.2.9 fix and it worked. The underlying causing exception was displayed within the stack trace.

Thanks again.

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Karl Baum commented

Hi Juergen. We are exploring our options here and I was wondering if it is valid to upgrade spring-hibernate to 1.2.9 but leave all other jars at 1.2.5. In reality I would rather just upgrade everything to Spring 2.0.3, but unfortunately I don't have the final say ;-).

thx.

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Paul Benedict commented

Since backported, ticket should add version 1.2.9 so issue appears in its release notes.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Karl Baum commented

I'm not quite sure I understand what you're saying.

Basically I am wondering if spring-hibernate-1.2.9 is compatible with the other 1.2.5 spring jars.

thx

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Juergen Hoeller commented

OK, marked this as backported to 1.2.9.

Karl, in principle, combining 1.2.9 extension jars with the 1.2.5 core should work fine. However, this does not constitute an officially supported combination! There might for example be some subtle issues with new utility methods in spring-core or the like.

So in general, I would recommend to do a full upgrade to 1.2.9. This should be seamless; you should not encounter any issues there. And if you do, we're willing to address anything you might find, either in the 1.2.9 final release (if reported in time) or in a 1.2.9a patch release (if necessary).

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Karl Baum commented

Sounds great. Thanks for your advice Juergen. Maybe I can convince the team to upgrade to 2.03 instead ;-). Problem is that I work on a very large team and it's not that easy. Really need to justify it.

Thanks again.

-karl

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 21, 2007

Juergen Hoeller commented

This is exactly why we offer 1.2.9: as an intermediate step up to 2.0.3 :-)

The intent is that 1.2.9 is a seamless upgrade from any 1.2.x release (mainly from 1.2.8), giving you a lot of little bug fixes, performance improvements and stability improvements without any breakages in backwards compatibility. 2.0.3 should not be a major pain to upgrade to either, but does incur some significant changes in the details, probably requiring a few specific parts of your application code to change (and implying a full test of the entire application to make sure that no side effects slipped in).

So for your scenario: In the short term, I'd recommend to go to 1.2.9 as soon as it is out (thoroughly testing the app against the current 1.2.9 snapshots already). Take the step up to 2.0.3 once you're able to leverage specific Spring 2.0 functionality, such as the in-depth JDK 1.5 support, AspectJ 5 support, JMS listener containers, etc (i.e. probably once you upgrade to WebLogic 9.x and hence JDK 1.5 as foundation).

Juergen

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Feb 22, 2007

Karl Baum commented

Thanks for the advice Juergen! That will be really helpful to our team.

-karl

@spring-projects-issues spring-projects-issues added in: data status: backported type: enhancement labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 2.0.3 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data status: backported type: enhancement
Projects
None yet
Development

No branches or pull requests

2 participants