For anyone in this situation (having to use a transaction filter), here
is a solution that uses a response wrapper to delay the redirect until
after the transaction has completed:
private class DelayedRedirectWrapper extends HttpServletResponseWrapper {
private String redirectLocation;
public DelayedRedirectWrapper(HttpServletResponse response) {
super(response);
}
@Override
public void sendRedirect(String location) throws IOException {
redirectLocation = location;
}
public void doCachedRedirect() throws IOException {
if ( redirectLocation != null ) {
super.sendRedirect( redirectLocation );
}
}
}
This is then used in the filter's doFilter method like this:
...
DelayedRedirectWrapper responseWrapper = new DelayedRedirectWrapper(
response );
beginTransaction();
filterChain.doFilter( request, wrappedResponse );
doCommit();
endTransaction();
responseWrapper.doCachedRedirect();
...
You could easily put the redirect-delaying code in it's own filter, for
re-usabilty.
iainr
Iain Reddick wrote:
Hi,
I'm working on a Wicket / Hibernate / Spring app, with a configuration
that uses spring's OSIV filter and my own transaction filter
(basically a transaction per-request pattern).
I've run into a problem involving the order of transaction commits and
redirect reponses (triggered by setResponsePage()).
The problem state is shown below:
1. User submits a form to create a new entity
2. Submit handler calls service to save new entity
3. Submit handler calls setResponsePage for page showing overview of
new entity
4. Wicket request cycle completes (I'm assuming this is where wicket
does the response.redirect())
5. Redirect is sent to browser
6. Browser requests new page, which fails as backing entity hasn't
been persisted yet
7. Transaction is commited, and new entity is persisted
This is obviously a race condition between 6 and 7 (i.e. if 6 and 7
are reversed, everything is OK).
Now, I'm aware that this isn't a wicket-specific issue, but the way
wicket works as a framework means that this situation is much more
likely than in a model 2 style framework.
Is transaction per-request using filters a reasonable configuration to
use with wicket and, if so, how can I ensure that any redirects occur
after my transaction has been committed?
(My guess is to use onBeginRequest and onEndRequest, but that assumes
that onEndRequest happens before redirection)
iainr
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]