Skip to Content
1
Former Member
Oct 03, 2014 at 10:15 AM

Cart concurrency issue

987 Views

Hi all,

We have implemented full AJAX cart updating system, in spite of this is a good approach in terms of performance we have realized to main issues:

  • When updating a cart concurrently we deals with errors of type "item 8842464264236 no longer valid (was removed): object no longer valid". Do NOTE different request from same user does not necesarily arrives in the same order neither takes the same time to been executed (obvious). In this scenario cart does not work as it should.

  • Our current solution is to serialize (in terms of implementation "synchronize" access) affected requests.

  • In spite of synchronizing access (no concurrent updates to the same user cart) the cart state for the request n+1 is not necessarily the same that at the end of the request n (I mean, sometimes cart entries are not up to date)

Find attached our current solution but I would like to discuss if this seems to be normal or any further advise

 /**
          * Synchronizes access to a affected methods and optionally refresh the cart before proceed.
          *
          * @param pjp
          *           the join point.
          * @param refreshCart
          *           whether to refresh the cart before proceed.
          * @return the original invocation result.
          * @throws Throwable
          *            in case of failure.
          */
         private Object doSynchronize(final ProceedingJoinPoint pjp, final boolean refreshCart) throws Throwable
         {
             final Object result;
     
             // Synchronization mutex is based on HTTP Session and standard Spring MVC behaviour
             // In other context may make sense employing the cart ID
             final HttpSession httpSession = WebSessionFunctions.getCurrentHttpSession();
             if (httpSession != null)
             {
                 final Object mutex = WebUtils.getSessionMutex(httpSession);
                 synchronized (mutex)
                 {
                     LOG.debug("Synchronizing transaction (\"" + pjp.getSignature().getName() + "\")with mutex: \"" + mutex + "\"");
     
                     // [1] - Refresh cart if needed (cart exist and is not up to date)
                     if (refreshCart && getCartService().hasSessionCart())
                     {
                         final CartModel cartModel = getCartService().getSessionCart();
     
                         if (!getModelService().isUpToDate(cartModel))
                         {
                             LOG.info("Refreshing cart \"" + cartModel.getCode() + "\" at \"" + pjp.getSignature().getName() + "\"");
                             getModelService().refresh(cartModel);
                         }
                     }
     
                     // [2] - Proceed
                     result = pjp.proceed(pjp.getArgs());
                 }
             }
             else
             {
                 LOG.warn("Unable to identify a mutex for current transaction. No JALO session found");
     
                 result = pjp.proceed(pjp.getArgs());
             }
     
             return result;
         }

[Spring AOP Java File][1] [1]: /storage/temp/1271-cartsynchronizationaspect.java.txt

[Spring Application Context XML File][2] [2]: /storage/temp/1272-spring-sync-config.xml.txt