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:[EMAIL PROTECTED] 
> Sent: Tuesday, July 01, 2003 8:19 PM
> To: [EMAIL PROTECTED]
> 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:
> 
> [EMAIL PROTECTED]
> [EMAIL PROTECTED]
> [EMAIL PROTECTED]
> [EMAIL PROTECTED]
> [EMAIL PROTECTED]
> 
> 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: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to