|
From: Andy D. <an...@ma...> - 2005-06-20 22:28:32
|
I'm attempting to do some advanced transaction synchronization. During
synchronization, I need to update a status row in a DB table. Of course,
since DB access is itself transactional, I create a new transaction for the
duration of the update using PROPAGATION_REQUIRES_NEW. The problem occurs
when I attempt to execute this in "afterCompletion". I sometimes get this
exception:
java.lang.IllegalStateException: No value for key
[org.hibernate.impl.SessionFactoryImpl@1f37bf1] bound to thread [Timer-3]
Here is an abbreviated version of my code:
------------
TransactionSynchronizationManager.registerSynchronization(new
TransactionSynchronization() {
public void suspend() { }
public void resume() { }
public void beforeCommit(boolean readOnly)
{
getTransactionTemplate().execute(new
TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(final TransactionStatus
status) {
update("update m_t set trans_time=null where trans_id=?",
new Object[] { transId });
}
});
}
public void beforeCompletion() { }
public void afterCompletion(final int status) {
getTransactionTemplate().execute(new
TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(final TransactionStatus
ts) {
if(status == STATUS_ROLLED_BACK) {
update("update m_t set s_last=trans_s_start, trans_id=null,
trans_time=null where trans_id=?",
new Object[] { transId} );
} else {
update("update m_t set trans_id=null, trans_time=null,
trans_s_start=null where trans_id=?",
new Object[] { transId });
}
}
});
}
});
---------------
The TransactionTemplate returned from getTransactionTemplate() was created
like this:
transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionTemplate.setTimeout(getTransactionTimeoutInMs());
transactionTemplate.setReadOnly(false);
My question is, should I be able to do this? The exception is not thrown in
many cases - however, in this particular case, an exception was thrown via
other code in the context of the main transaction, though it did not cause a
rollback to occur, so the transaction was in the process of being committed -
and while committing the main transaction, the process of starting a new
transaction caused this related exception to be thrown.
This is against Spring 1.2.1.
- Andy
PS. Here is a full stack trace, for what its worth:
java.lang.IllegalStateException: No value for key
[org.hibernate.impl.SessionFactoryImpl@1f37bf1] bound to thread [Timer-3]
at
org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:175)
at
org.springframework.orm.hibernate3.SessionFactoryUtils$SpringSessionSynchronization.suspend(SessionFactoryUtils.java:846)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.suspend(AbstractPlatformTransactionManager.java:350)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.getExistingTransaction(AbstractPlatformTransactionManager.java:271)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:215)
at
org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:111)
at com.marathon.service.dao.jdbc.PSDAO$2.afterCompletion(PSDAO.java:185)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:610)
at
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:467)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.doCloseTransactionAfterThrowing(TransactionAspectSupport.java:294)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at
net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy58.postApproved(Unknown Source)
|