tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stefan Radzom" <srad...@web.de>
Subject RE: How to synchronize based on session? (Prevent multiple submissions of forms)
Date Tue, 01 Jul 2003 22:30:04 GMT
There is a lifecycle events fired upon creation of a new session. You may
want to implement and register your own
javax.servlet.http.HttpSessionListener to put the attribute in the session. 

-Stefan

> -----Original Message-----
> From: Raiden [mailto:raiden@wonko.inow.com] 
> Sent: Wednesday, July 02, 2003 12:02 AM
> To: Tomcat Users List
> Subject: RE: How to synchronize based on session? (Prevent 
> multiple submissions of forms)
> 
> 
> Here's a thread that's discussing the same problem.  Though 
> it's referring
> to the use made in the Struts code, and I'm just talking about a small
> synchronize call, it's essentially the same issue.  If the 
> best way is to
> synchronize on an object that's in the session, how do you 
> properly get
> that object in the session in the first place?  (It's almost 
> a circular
> problem).
> 
> Here's the thread:
> http://www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg4
> 1219.html
> 
> Thanks again for your help!
> 
> -Raiden
> 
> 
> 
> On Tue, 1 Jul 2003, Raiden wrote:
> 
> > Hi Stefan,
> >
> > Thanks for the explanation.  That makes sense, except how 
> can you make
> > sure that the object is added to the session only once, 
> when the session
> > is created?
> >
> > It would seem like you would need to synchronize on 
> something else for
> > adding the object to the session, because there might be a race
> > condition (unless there is a special bit of code that is 
> only ever called
> > once, when the session is created).  Otherwise, two 
> different threads
> > might each have their own instance of the lock object.
> >
> > How do I guarantee that the lock object is only created 
> once, at the time
> > the session is created?
> >
> > Thanks,
> > Raiden
> >
> >
> > On Tue, 1 Jul 2003, Stefan Radzom wrote:
> >
> > > For security reasons your are not handed the internal
> > > org.apache.catalina.session.StandardSession . Instead, 
> the implicit session
> > > you are trying to synchronize holds a reference to
> > > org.apache.catalina.session.StandardSessionFacade which 
> is backed by the
> > > actual StandardSession to which all method calls are 
> delegated. The facade
> > > object can therefore change between different requests, 
> thus making it not
> > > appropriate for synchronisation.
> > >
> > > Try putting a dummy object into the session when creating 
> a new session:
> > > session.setAttribute("lock", new Object()) . On 
> subsequent requests you can
> > > get the attribute and obtain a lock on this object.
> > >
> > > Object lock = session.getAttribute("lock");
> > > synchronized (lock) { ; }
> > >
> > > -Stefan
> > >
> > >
> > > > -----Original Message-----
> > > > From: Raiden [mailto:raiden@wonko.inow.com]
> > > > Sent: Tuesday, July 01, 2003 8:19 PM
> > > > To: tomcat-user@jakarta.apache.org
> > > > Subject: How to synchronize based on session? (Prevent
> > > > multiple submissions of forms)
> > > >
> > > >
> > > > Hello,
> > > >
> > > > We are trying to prevent the "multiple submission of a 
> form problem",
> > > > that can result when a user double-clicks the submit button.
> > > > We have a
> > > > process in place, but we have been unable to get the 
> session based
> > > > synchronization to work correctly.
> > > >
> > > > Our order page submits to a "meta-refresh" page that 
> checks to see the
> > > > current status of the order processing each time it loads.
> > > > If there is
> > > > an error, it sends the user back to the order page.  If 
> the order was
> > > > successful, the user is sent to the success page.  If the
> > > > order is still
> > > > processing, it refreshes in 5 seconds (and meanwhile, 
> the user has a
> > > > pretty 5 second progress bar to watch).  However, The
> > > > relevant snippet of
> > > > code is below:
> > > >
> > > > String nextUrl = null;
> > > > synchronized (session) {
> > > >   BigDecimal status =
> > > >     (BigDecimal)session.getAttribute(SiteProps.PROCESS_STATUS);
> > > >
> > > >   if (status != null) {
> > > >     System.out.println("  Processing has already begun. 
>  Checking
> > > > status.");
> > > >
> > > >     if (status.equals(SiteProps.PROCESS_SUCCESS)) {
> > > >       System.out.println("  We already know it was approved.
> > > > Just showing
> > > > them the success page.");
> > > >       nextUrl = "/success.jsp";
> > > >       
> response.sendRedirect(response.encodeRedirectUrl(nextUrl));
> > > >       return;  // will remove status object on next page
> > > >     } else if (status.equals(SiteProps.PROCESS_ERROR)) {
> > > >       System.out.println("  We know the credit card charge
> > > > failed.  Send
> > > > them back to the order form.");
> > > >       nextUrl = "/order.jsp";
> > > >       
> response.sendRedirect(response.encodeRedirectUrl(nextUrl));
> > > >       return;  // will remove status object on next page
> > > >     } else if (status.equals(SiteProps.PROCESS_UNKNOWN)) {
> > > >       System.out.println("  Still processing.  Not sure what
> > > > the result
> > > > will be.  This page will refresh in 5 seconds.");
> > > >       nextUrl = "/order_check.jsp"; // refresh back to 
> this same page
> > > >     }
> > > >   } else {
> > > >     // we don't have any record of a previous attempt to process
> > > >     System.out.println("  First time trying to process 
> order page.
> > > > Starting processing, scheduling a refresh.");
> > > >     session.setAttribute(SiteProps.PROCESS_STATUS,
> > > >       SiteProps.PROCESS_UNKNOWN);
> > > >   }
> > > >   %>
> > > >   <html>
> > > >     <!-- progress bar animated gif html code here -->
> > > >   </html>
> > > >   <%
> > > >   if (nextUrl == null) {
> > > >     // first time to page
> > > >
> > > >     // order processing code here
> > > >   }
> > > > }
> > > >
> > > > The problem is, that there isn't any real synchronization
> > > > here.  This is
> > > > because the "session" object is a different object each 
> time this page
> > > > loads.  In fact, printing out the "session" object each 
> time the page
> > > > loads results in:
> > > >
> > > > org.apache.catalina.session.StandardSessionFacade@24ea85
> > > > org.apache.catalina.session.StandardSessionFacade@10275fa
> > > > org.apache.catalina.session.StandardSessionFacade@18706f6
> > > > org.apache.catalina.session.StandardSessionFacade@f1f34a
> > > > org.apache.catalina.session.StandardSessionFacade@fb6763
> > > >
> > > > Since the session object keeps changing, what is the 
> proper way to
> > > > synchronize based on the user's session, to make this
> > > > anti-double-process
> > > > code work properly?
> > > >
> > > > This middle page with the progress bar helps to remove 
> most of our
> > > > double-click problems, but occassionally a user is able to
> > > > get multiple
> > > > copies of this "progress page" opened, and then if the timing
> > > > is right,
> > > > they both enter that snippet of code above at the same time,
> > > > both think
> > > > it's the first time this page is being processed, and both
> > > > run the order
> > > > processing code.
> > > >
> > > > Thank you,
> > > > Raiden
> > > >
> > > >
> > > > 
> ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: 
> tomcat-user-unsubscribe@jakarta.apache.org
> > > > For additional commands, e-mail: 
> tomcat-user-help@jakarta.apache.org
> > > >
> > > >
> > >
> > >
> > >
> > > 
> ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail: 
> tomcat-user-help@jakarta.apache.org
> > >
> >
> > 
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Mime
View raw message