Ensure async Callables are in sync with the call stack

After this change each call stack level pushes and pops an async
Callable to ensure the AsyncExecutionChain is in sync with the
call stack. Before this change, a controller returning a "forward:"
prefixed string caused the AsyncExecutionChain to contain a
extra Callables that did not match the actual call stack.

Issue: SPR-9611
This commit is contained in:
Rossen Stoyanchev
2012-07-20 10:54:58 -04:00
parent 33a3681975
commit 6cc512b51c
27 changed files with 240 additions and 239 deletions

View File

@@ -187,7 +187,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
SessionHolder sessionHolder = new SessionHolder(session);
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
chain.addDelegatingCallable(getAsyncCallable(request, sessionFactory, sessionHolder));
chain.push(getAsyncCallable(request, sessionFactory, sessionHolder));
}
}
else {
@@ -204,21 +204,20 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
try {
filterChain.doFilter(request, response);
}
finally {
if (!participate) {
if (isSingleSession()) {
// single session mode
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
if (chain.isAsyncStarted()) {
if (!chain.pop()) {
return;
}
logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
closeSession(sessionHolder.getSession(), sessionFactory);
}
else {
if (chain.isAsyncStarted()) {
if (!chain.pop()) {
throw new IllegalStateException("Deferred close is not supported with async requests.");
}
// deferred close mode
@@ -303,7 +302,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
public Object call() throws Exception {
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
try {
getNextCallable().call();
getNext().call();
}
finally {
SessionHolder sessionHolder =

View File

@@ -181,7 +181,7 @@ public class OpenSessionInViewInterceptor extends HibernateAccessor implements A
return new AbstractDelegatingCallable() {
public Object call() throws Exception {
TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
getNextCallable().call();
getNext().call();
return null;
}
};

View File

@@ -119,7 +119,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
SessionHolder sessionHolder = new SessionHolder(session);
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
chain.addDelegatingCallable(getAsyncCallable(request, sessionFactory, sessionHolder));
chain.push(getAsyncCallable(request, sessionFactory, sessionHolder));
}
try {
@@ -130,7 +130,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
if (!participate) {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
if (chain.isAsyncStarted()) {
if (!chain.pop()) {
return;
}
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
@@ -198,7 +198,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
public Object call() throws Exception {
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
try {
getNextCallable().call();
getNext().call();
}
finally {
SessionHolder sessionHolder =

View File

@@ -137,7 +137,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor
return new AbstractDelegatingCallable() {
public Object call() throws Exception {
TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
getNextCallable().call();
getNext().call();
return null;
}
};