Error while saving the item to cart

839 views
Skip to first unread message

atg.d...@gmail.com

unread,
Oct 15, 2007, 10:37:53 PM10/15/07
to ATG_Tech
Hi All,

I am getting the following error while adding the item to cart (@
second time) when the same item is deleted at first time in the same
user session after some time gap (i.e after 3 mins with the same user
session at second attempt to add the same item).

The error is :

Saving order o4550231 failed because doing so would result in data
being overwritten. Order data for your browser window was out of date.
Please re-submit your changes for them to take effect.

The order number remains same at each time to the same user (though
the sessions are different).
eg. user1 --- o1234
user2 --- o2345

Can anybody help me sort out the error.

Thanks.

Khalid

unread,
Oct 16, 2007, 8:56:29 PM10/16/07
to ATG_Tech
when deleting / adding items, you have to make sure to delete/add
proper relationships (payment groups etc / payment groups etc), i
believe there is a method:
cItem.removeAllRelationshipsFromCommerceItem(order, commerceItemId);

see documentation.

On Oct 15, 7:37 pm, "atg.dyn...@gmail.com" <atg.dyn...@gmail.com>
wrote:

Jeremy Sears

unread,
Oct 16, 2007, 9:38:59 PM10/16/07
to atg_...@googlegroups.com
This error will occur when you modify the same order in two different sessions.  This can occur if you log in as the same user or utilize two browser windows to modify the same order. 

ATG Commerce utilizes optimistic locking to protect the order from concurrent modification between reads.  To do this, it maintains the last order version in memory when the order is read from the database.  When the order is written, this version number is incremented.  If a thread attempts to update the order and discovers that the in-memory version number is different than the database version number, then the system knows that another thread updated the order between the time that this thread read the order and when the update was initiated.

The error itself is harmless.  It just lets the user know that the information they had on screen was stale.  The page refreshes, and they can continue from where they were by re-submitting their last request.
--
Jeremy Sears

ATG Dynamo

unread,
Oct 16, 2007, 10:59:35 PM10/16/07
to atg_...@googlegroups.com
Hi Jeremy,

Thanks for you clear information. In my case i am using the same browser under the same session. And if i modify the order with out any time gap, its working fine. If i try to modify ( remove) the same item after some time (eg. 3 mins ) its giving the error and every time for the same user giving same order number. Can u give me a good solution.

pobrienATG

unread,
Oct 17, 2007, 9:02:27 AM10/17/07
to ATG_Tech
In the first message, you said the sessions were different. If they
are different, then the only solution is likely to lengthen the
session timeout (3 minutes seems really short).

If it is the same session, then I don't understand why you are seeing
the error. Is there some custom code that is being invoked during the
process? Is there a background process running that could modify the
order?

On Oct 16, 10:59 pm, "ATG Dynamo" <atg.dyn...@gmail.com> wrote:
> Hi Jeremy,
>
> Thanks for you clear information. In my case i am using the same browser
> under the same session. And if i modify the order with out any time gap, its
> working fine. If i try to modify ( remove) the same item after some time
> (eg. 3 mins ) its giving the error and every time for the same user giving
> same order number. Can u give me a good solution.
>

> On 10/16/07, Jeremy Sears <jsears....@gmail.com> wrote:
>
>
>
>
>
> > This error will occur when you modify the same order in two different
> > sessions. This can occur if you log in as the same user or utilize two
> > browser windows to modify the same order.
>
> > ATG Commerce utilizes optimistic locking to protect the order from
> > concurrent modification between reads. To do this, it maintains the last
> > order version in memory when the order is read from the database. When the
> > order is written, this version number is incremented. If a thread attempts
> > to update the order and discovers that the in-memory version number is
> > different than the database version number, then the system knows that
> > another thread updated the order between the time that this thread read the
> > order and when the update was initiated.
>
> > The error itself is harmless. It just lets the user know that the
> > information they had on screen was stale. The page refreshes, and they can
> > continue from where they were by re-submitting their last request.
> > --
> > Jeremy Sears
>

> > On 10/16/07, Khalid <khalid.khal...@gmail.com> wrote:
>
> > > when deleting / adding items, you have to make sure to delete/add
> > > proper relationships (payment groups etc / payment groups etc), i
> > > believe there is a method:
> > > cItem.removeAllRelationshipsFromCommerceItem(order, commerceItemId);
>
> > > see documentation.
>
> > > On Oct 15, 7:37 pm, "atg.dyn...@gmail.com" <atg.dyn...@gmail.com>
> > > wrote:
> > > > Hi All,
>
> > > > I am getting the following error while adding the item to cart (@
> > > > second time) when the same item is deleted at first time in the same
> > > > user session after some time gap (i.e after 3 mins with the same user
> > > > session at second attempt to add the same item).
>
> > > > The error is :
>
> > > > Saving order o4550231 failed because doing so would result in data
> > > > being overwritten. Order data for your browser window was out of date.
>
> > > > Please re-submit your changes for them to take effect.
>
> > > > The order number remains same at each time to the same user (though
> > > > the sessions are different).
> > > > eg. user1 --- o1234
> > > > user2 --- o2345
>
> > > > Can anybody help me sort out the error.
>

> > > > Thanks.- Hide quoted text -
>
> - Show quoted text -

Jeremy Sears

unread,
Oct 17, 2007, 10:26:14 AM10/17/07
to atg_...@googlegroups.com
I'm not sure what code you are executing or what extensions you have made to that code, but I'll venture a guess.  Perhaps you are modifying the order in a transaction and not calling OrderManager.updateOrder before the transaction completes?  I would expect that the timing of the updates would not play a part if you had done so, so that may not be the problem.

Another possibility is that there is a back-end service, such as a scheduled service, which is updating the order outside of a request thread. 

Is this a multi-server environment, or is this reproducible on a single server environment?

Is there anything that could have modified the order between when it was loaded and when it was updated?  If you're not sure, you could turn loggingDebug on in the OrderRepository to see if any updates occur.

Could you also clarify whether or not this is a single session?  Your emails are contradictory.

BTW, this list is maintained and moderated by ATG developers who have volunteered to do so.  We will all be on the atg_tech group, so that's a great reason to keep technical conversations here, rather than on another list.  You are all welcome to discuss ATG in any forum you desire, but the experts will be here.
--
Jeremy Sears


ATG Dynamo

unread,
Oct 17, 2007, 11:09:34 AM10/17/07
to atg_...@googlegroups.com
Thanks for your time. The jboss is running under clustered environment (multi server environment) and my session isa single user session.

> user session after some time gap (i.e after 3 mins with th e same user

Jeremy Sears

unread,
Oct 17, 2007, 3:49:16 PM10/17/07
to atg_...@googlegroups.com
Is it possible that your requests are being routed to different JBoss server instances?  This is still sounding like a case where updates are happening in different sessions.  If the requests were not routed to the same JBoss server instance, then new sessions may be spawned on the other servers.  What infrastructure to you have in front of your app-server (load balancers, web-servers, web-server plugins, proxies, etc.)?

Do you have any answers to the rest of our questions?  It is very difficult to help with so little background information -- we're shooting in the dark.
--
Jeremy Sears


Pete Hawkins

unread,
Oct 17, 2007, 7:04:54 PM10/17/07
to atg_...@googlegroups.com
A few common things to look at:

Ensure you're using sticky sessions.

Check using advised transaction isolation level in your database
deployment descriptor.

Verify that your point-releases of ATG and JBoss do not suffer from
known cluster-related issues.

Regards,
Pete Hawkins

atg.d...@gmail.com

unread,
Oct 22, 2007, 9:11:30 AM10/22/07
to ATG_Tech
Hi All,

Thanks for your valuable information. I got to resolve the bug.

On Oct 17, 4:04 pm, "Pete Hawkins" <hawkins.p...@gmail.com> wrote:
> A few common things to look at:
>
> Ensure you're using sticky sessions.
>
> Check using advised transaction isolation level in your database
> deployment descriptor.
>
> Verify that your point-releases of ATG and JBoss do not suffer from
> known cluster-related issues.
>
> Regards,
> Pete Hawkins
>

> On 17/10/2007, Jeremy Sears <jsears....@gmail.com> wrote:
>
> > Is it possible that your requests are being routed to different JBoss server
> > instances? This is still sounding like a case where updates are happening
> > in different sessions. If the requests were not routed to the same JBoss
> > server instance, then new sessions may be spawned on the other servers.
> > What infrastructure to you have in front of your app-server (load balancers,
> > web-servers, web-server plugins, proxies, etc.)?
>
> > Do you have any answers to the rest of our questions? It is very difficult
> > to help with so little background information -- we're shooting in the dark.
> > --
> > Jeremy Sears
>

> > On 10/17/07, ATG Dynamo <atg.dyn...@gmail.com> wrote:
> > > Thanks for your time. The jboss is running under clustered environment
> > (multi server environment) and my session isa single user session.
>

> > > On 10/17/07, Jeremy Sears <jsears....@gmail.com> wrote:
>
> > > > I'm not sure what code you are executing or what extensions you have
> > made to that code, but I'll venture a guess. Perhaps you are modifying the
> > order in a transaction and not calling OrderManager.updateOrder before the
> > transaction completes? I would expect that the timing of the updates would
> > not play a part if you had done so, so that may not be the problem.
>
> > > > Another possibility is that there is a back-end service, such as a
> > scheduled service, which is updating the order outside of a request thread.
>
> > > > Is this a multi-server environment, or is this reproducible on a single
> > server environment?
>
> > > > Is there anything that could have modified the order between when it was
> > loaded and when it was updated? If you're not sure, you could turn
> > loggingDebug on in the OrderRepository to see if any updates occur.
>
> > > > Could you also clarify whether or not this is a single session? Your
> > emails are contradictory.
>
> > > > BTW, this list is maintained and moderated by ATG developers who have
> > volunteered to do so. We will all be on the atg_tech group, so that's a
> > great reason to keep technical conversations here, rather than on another
> > list. You are all welcome to discuss ATG in any forum you desire, but the
> > experts will be here.
> > > > --
> > > > Jeremy Sears
>

> > > > On 10/16/07, ATG Dynamo < atg.dyn...@gmail.com> wrote:
>
> > > > > Hi Jeremy,
>
> > > > > Thanks for you clear information. In my case i am using the same
> > browser under the same session. And if i modify the order with out any time
> > gap, its working fine. If i try to modify ( remove) the same item after some
> > time (eg. 3 mins ) its giving the error and every time for the same user
> > giving same order number. Can u give me a good solution.
>

> > > > > On 10/16/07, Jeremy Sears < jsears....@gmail.com> wrote:
>
> > > > > > This error will occur when you modify the same order in two
> > different sessions. This can occur if you log in as the same user or
> > utilize two browser windows to modify the same order.
>
> > > > > > ATG Commerce utilizes optimistic locking to protect the order from
> > concurrent modification between reads. To do this, it maintains the last
> > order version in memory when the order is read from the database. When the
> > order is written, this version number is incremented. If a thread attempts
> > to update the order and discovers that the in-memory version number is
> > different than the database version number, then the system knows that
> > another thread updated the order between the time that this thread read the
> > order and when the update was initiated.
>
> > > > > > The error itself is harmless. It just lets the user know that the
> > information they had on screen was stale. The page refreshes, and they can
> > continue from where they were by re-submitting their last request.
> > > > > > --
> > > > > > Jeremy Sears
>

Jeremy Sears

unread,
Oct 22, 2007, 12:33:49 PM10/22/07
to atg_...@googlegroups.com
Would you mind sharing the problem and solution with the group, in case anyone encounters this issue in the future?

Thanks.
--
Jeremy Sears

atg.d...@gmail.com

unread,
Oct 22, 2007, 12:49:55 PM10/22/07
to ATG_Tech
Well, while updating the order we should always take care about
transactions, so i made it undear a transaction.

On Oct 22, 9:33 am, "Jeremy Sears" <jsears....@gmail.com> wrote:
> Would you mind sharing the problem and solution with the group, in case
> anyone encounters this issue in the future?
>
> Thanks.
> --
> Jeremy Sears
>

Jeremy Sears

unread,
Oct 22, 2007, 1:08:29 PM10/22/07
to atg_...@googlegroups.com
Thanks for the update.  In general, the design pattern for updating an order is as follows:

1) Acquire lock-manager write lock on profile id from the /atg/commerce/order/LocalLockManager
2) Begin Transaction
3) Synchronize on the Order object.
4) Modify Order
5) Call OrderManager.updateOrder()
6) Release Order synchronization
7) End Transaction
8) Release lock-manager write lock on profile id from the /atg/commerce/order/LocalLockManager

If you extend atg.commerce.order.purchase.PurchaseProcessFormHander, then steps 1,2,7 & 8 are done for you in the beforeSet and afterSet method implementations.  Steps 3&6 are no longer strictly necessary, but are still good practice.  Steps 3-6 should be performed manually in your application code.  Calling step 5 within the transaction is mandatory and the lock manager work should always wrap the transaction to prevent some rare transaction race conditions.

Good luck, and thanks again for the update.
--
Jeremy Sears




> > > > > > > > > > user session after some time gap ( i.e after 3 mins with th

atg.d...@gmail.com

unread,
Oct 22, 2007, 1:13:23 PM10/22/07
to ATG_Tech
Thanks Jeremy,

I used to get RollBackException (like rollback already marked
exception) while updating the order. Can you tell me some thing about
this.

On Oct 22, 10:08 am, "Jeremy Sears" <jsears....@gmail.com> wrote:
> Thanks for the update. In general, the design pattern for updating an order
> is as follows:
>
> 1) Acquire lock-manager write lock on profile id from the
> /atg/commerce/order/LocalLockManager
> 2) Begin Transaction
> 3) Synchronize on the Order object.
> 4) Modify Order
> 5) Call OrderManager.updateOrder()
> 6) Release Order synchronization
> 7) End Transaction
> 8) Release lock-manager write lock on profile id from the
> /atg/commerce/order/LocalLockManager
>
> If you extend atg.commerce.order.purchase.PurchaseProcessFormHander, then
> steps 1,2,7 & 8 are done for you in the beforeSet and afterSet method
> implementations. Steps 3&6 are no longer strictly necessary, but are still
> good practice. Steps 3-6 should be performed manually in your application
> code. Calling step 5 within the transaction is mandatory and the lock
> manager work should always wrap the transaction to prevent some rare
> transaction race conditions.
>
> Good luck, and thanks again for the update.
> --
> Jeremy Sears
>

> > > > > > > > > > > > user session after some time gap (i.e after 3 mins

Jeremy Sears

unread,
Oct 22, 2007, 9:30:40 PM10/22/07
to atg_...@googlegroups.com
A roll back exception can occur if you attempt to utilize a transaction that has been marked for rollback.  Often services will flag a transaction for rollback-only if an exception occurs.  If the transaction is used (typically by attempting to enlist another resource in the transaction) after it has been flagged for rollback-only, then a rollback exception will be thrown.

This can sometimes happen in code that catches and logs an exception, but allows processing to continue.  If the subsequent processing attempts to utilize the transaction, then you may see this error.  In cases like this, it is best to simply re-throw the exception up to a piece of code that will catch it, log it, and return.  Often times, the code that should ultimately log and swallow the exception is a form-handler.  You may find, in some cases, that you are writing a piece of code that can only throw a specific exception type and you have caught an exception of a different type.  In these cases, it is advisable to wrap the caught exception in the type that is throwable and to set the "cause" exception of the new exception using the java.lang.Exception#Exception(String,Throwable) or java.lang.Exception#Exception(Throwable) compatible constructors of the destination Exception subclass.  For example:

public void doSomething() throws SomeException{

  try{
    doSomethingElse()
  }catch(SomeOtherException soe){
    new SomeException("Exception occurred while doing something.", soe);
  }
}

This allows you to convert exceptions to whatever type you need, while making sure the proper exception handler handles the exception.  If the doSomethingElse() method had marked the transaction for rollback, the code that calls the doSomething() should be able to abort properly.  However, if the doSomething() method simply catches and logs the exception, then the code which calls doSomething() may not abort properly and may attempt to continue utilizing the transaction, causing a rollback exception.

There are probably other cases where you can cause rollback exceptions to occur, but the above is a common mistake I've seen.

Another case you might get this is if you had code which opens a transaction, encounters and error flagging the transaction for rollback, then *forwards* (rather than redirects) to an error URL.  Some app-server vendors would execute the rendering of the forward in the context of the transaction that was rolled back.  If that was the case, a rollback exception would occur.  With ATG2007.1, we normalized the behavior, such that the forward will be executed in its own transaction on all app-servers.  If you encounter this problem prior to 2007.1, try using redirects rather than forwards.
--
Jeremy Sears

atg.d...@gmail.com

unread,
Oct 23, 2007, 12:12:14 PM10/23/07
to ATG_Tech
I was getting the rollbackexception becasue, have written the
transaction part in try, catch and finally. and rollback in catch and
commit in finally. When an exception encounter then control goes to
catch and after that finally will be executed, here in catch block
transaction already marked to rollback and finally its going to
finally black and will ececute commit() in finally block. So i removed
commit() from finally and placed after updateOrder(). Its working
fine.

> ...
>
> read more »

atg.d...@gmail.com

unread,
Oct 23, 2007, 12:39:42 PM10/23/07
to ATG_Tech, sair...@gmail.com
Hi Jeremy,

I am getting the same error again, can you please look into the code
and am sending the code.

public boolean
handleRemoveInternetMerchantItemFromOrder(DynamoHttpServletRequest
pRequest, DynamoHttpServletResponse pResponse)
throws ServletException, IOException {
try {

TransactionManager tm = getTransactionManager();
TransactionDemarcation td = null;
td = new TransactionDemarcation();

try {
td.begin(tm);


Order order = getInternetMerchantOrder();
List items = order.getCommerceItems();
if (items != null) {
for (int i = 0; i < items.size(); i++) {

CommerceItem item = (CommerceItem) items.get(i);
String catalogRefId = item.getCatalogRefId();
String removeCatalogRefId = getInternetMerchantCatalogRefId();
if (catalogRefId.equals(removeCatalogRefId)) {
ShippingGroupCommerceItemRelationship sgrel = null;
Iterator iter =
item.getShippingGroupRelationships().iterator();
while (iter.hasNext()) {
sgrel = (ShippingGroupCommerceItemRelationship) iter.next();
ShippingGroup sg = sgrel.getShippingGroup();

getHandlingInstructionManager().removeHandlingInstructionsFromShippingGroup(order,
sg.getId(), item.getId());
}
long qty = item.getQuantity();

getCommerceItemManager().removeAllRelationshipsFromCommerceItem(order,
item.getId());
getCommerceItemManager().removeItemFromOrder(order,
item.getId());
}
}
}
getOrderManager().updateOrder(order);
Map extraParams = createRepriceParameterMap();
runProcessRepriceOrder(getModifyOrderPricingOp(), order,
getUserPricingModels(), getUserLocale(), getProfile(), extraParams);
tm.commit();

} catch (TransactionDemarcationException tde) {
tm.rollback();
if (isLoggingError())
logError(tde);
} finally {
try {
td.end();
} catch (TransactionDemarcationException tde) {
if (isLoggingError())
logError(tde);
}
}

} catch (Exception exc) {
processException(exc, MSG_ERROR_UPDATE_ORDER, pRequest, pResponse);
}
return checkFormRedirect(getSetOrderSuccessURL(),
getSetOrderErrorURL(), pRequest, pResponse);
}


and the error is :

atg.commerce.order.purchase.CartModifierFormHandler]
atg.commerce.order.InvalidVersionException: This order (o95001) is out
of date. Changes have been made to the order and the operation should
be resubmitted. Order version 11, Repository item version 12.
at atg.commerce.order.OrderManager.updateOrder(OrderManager.java:
2557)
at
com.personalshopper.estore.order.purchase.PersonalShopperCartModifier.handleRemoveInternetMerchantItemFromOrder(PersonalShopperCartModifier.java:
451)


On Oct 23, 9:12 am, "atg.dyn...@gmail.com" <atg.dyn...@gmail.com>
wrote:

> ...
>
> read more »

Belmont, Adam

unread,
Oct 23, 2007, 2:14:35 PM10/23/07
to atg_...@googlegroups.com, sair...@gmail.com
Hi,
In general your transaction code should follow this pattern:

TransactionDemarcation td = new TranactionDemarcation();
boolean rollback = true;
try {
td.begin(getTransactionManager());
// Do Transactional Work Here
rollback = false;
} finally {
td.end(rollback);
}


If you keep the rollback variable set to true until the very end then it
makes logic a little simpler. You don't need to worry about explicitly
calling rollback or commit, just pass the rollback flag into the td.end()
method.

Hope this helps.

-- Adam


Hi Jeremy,

try {
td.begin(tm);


and the error is :


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"ATG_Tech" group.
To post to this group, send email to atg_...@googlegroups.com
To unsubscribe from this group, send email to
atg_tech-u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/atg_tech?hl=en
-~----------~----~----~----~------~----~------~--~---

Jeremy Sears

unread,
Oct 23, 2007, 8:58:36 PM10/23/07
to atg_...@googlegroups.com, sair...@gmail.com
A few additional comments.  What Adam suggests is completely correct please follow his suggestions. 

Also:
- Move the OrderManger.updateOrder() call to after the runProcessRepriceOrder() call. 
- Remove the tm.commit() and tm.rollback() calls.  The TransactionDemarcation will manage that for you if you follow Adam's suggestion.
- Remove both TransactionDemarcationException catch blocks.  They will be handled by your other catch block, which will also properly create a form exception.

What class does this subclass?  If it is not a subclass of PurchaseProcessFormHandler (or its subclasses), then there is more that needs to be done.

All of this will fix various bugs in your code, but it will not solve your invalid version exception.  For that, you should follow the suggestions laid out earlier in the thread.  The invalid version exceptions happen when you update the same order from multiple threads.  What is the implementation of your getInternetMerchantOrder() method?  Could you provide the source for that?  If it is set via configuration, could you provide the configuration?  If that is configured to reference another component (such as an OrderHolder), could you provide the configuration for that component as well as any customizations you have made to that component?
--
Jeremy Sears


lokivog

unread,
Oct 24, 2007, 2:02:34 PM10/24/07
to ATG_Tech
To "solve" your version exception issue, call updateVersion right
before updateOrder

((OrderImpl) order).updateVersion( );
getOrderManager().updateOrder(order);

If you have extended order then obviously you cast it to your order
class.

Note: If you are getting a version exception then you are updating the
order outside of handleRemoveInternetMerchantItemFromOrder but right
before the method which is a bad thing. You should always be aware
of when and how the order is being updated.

Michael


On Oct 23, 11:39 am, "atg.dyn...@gmail.com" <atg.dyn...@gmail.com>
wrote:

> ...
>
> read more »

atg.d...@gmail.com

unread,
Oct 30, 2007, 4:04:45 PM10/30/07
to ATG_Tech
Hi All.

Again am getting the same error but in this case happening while
adding the item to cart..

> ...
>
> read more »

lokivog

unread,
Oct 31, 2007, 10:25:01 AM10/31/07
to ATG_Tech
After looking at your handleRemoveInternetMerchantItemFromOrder, it
looks like your trying to reinvent the wheel. ATG provides the
functionality for removing and adding an item from your cart thus
eliminating the pain you seem to be enduring. Take a look at the
CartModifierFormHandler, it has a handleRemoveItemFromOrder that you
could be using instead of your
handleRemoveInternetMerchantItemFromOrder. Your method does not do
anything custom that would require it's own custom remove method. The
only thing it is doing is removing an item based on the
getInternetMerchantCatalogRefId(), why not just add the
InternetMerchantCatalogRefId to the
CartModifierFormHandler.removalCommerceIds property in the
preRemoveItemFromOrder and I think you'll see the same results. As
far as your extraParams map for repricing the order, if you do indeed
have custom pricing that would require extraParams then you can always
reprice the order again in the postRemoveItemFromOrder or just use the
repriceOrderDroplet in your jsp page. It is very easy to extend the
repriceOrderDroplet so that you can pass your extraParams in it.

Your question was in regards to an error in the add item to cart. I
say all this because I suspect you can utilize the
CartModifierFormHandler.handleAddItemToOrder method and elevate the
need for a custom add item to order method and all the errors your
encountering with custom methods.

Michael


On Oct 30, 3:04 pm, "atg.dyn...@gmail.com" <atg.dyn...@gmail.com>
wrote:

> ...
>
> read more »

atg.d...@gmail.com

unread,
Nov 1, 2007, 4:05:21 PM11/1/07
to ATG_Tech
Its working fine now. I made one change, i.e added updateVersion()
before to updateOrder(), got resolved. Thanks for all.

> ...
>
> read more »

Reply all
Reply to author
Forward
0 new messages