ATG Code not following the recommended update order approach?

2,187 views
Skip to first unread message

Devon Hillard

unread,
Oct 23, 2008, 12:55:00 PM10/23/08
to ATG_Tech
I've found multiple places in OOB code in ATG 2006.3 where an order is
updated without a transaction, without syncronization, and without
calling updateVersion(), which leads to ConcurrentUpdateExceptions.

Currently I'm seeing an error from here: ProcUpdateOrderRepository

Any ideas (other than replacing the ATG class with one that does the
sync and updateVersion and all that?

**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller ---
CONTAINER:atg.commerce.CommerceException;
SOURCE:CONTAINER:atg.service.pipeline.RunProcessException: An
exception was thrown from the context of the link named
[updateOrderObject].; SOURCE:CONTAINER:atg.commerce.CommerceException:
Saving order A100000810 failed because doing so would result in data
being overwritten. This save attempt had an out of date repository
item [order].; SOURCE:atg.repository.ConcurrentUpdateException: no
rows updated oldVersion=45 for item=order:A100000810 in
GSATransaction=atg.adapter.gsa.GSATransaction@1ed902c
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2589)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.processor.ProcUpdateOrderRepository.runProcess(ProcUpdateOrderRepository.java:
100)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.OrderFulfillerModificationHandler.handleModifyOrderNotification(OrderFulfillerModificationHandler.java:
229)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.OrderFulfiller.handleMessage(OrderFulfiller.java:
253)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.FulfillerSystem.receiveMessage(FulfillerSystem.java:
454)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller ....stack trace CROPPED after 10 lines.
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller Caused
by :CONTAINER:atg.service.pipeline.RunProcessException: An exception
was thrown from the context of the link named [updateOrderObject].;
SOURCE:CONTAINER:atg.commerce.CommerceException: Saving order
A100000810 failed because doing so would result in data being
overwritten. This save attempt had an out of date repository item
[order].; SOURCE:atg.repository.ConcurrentUpdateException: no rows
updated oldVersion=45 for item=order:A100000810 in
GSATransaction=atg.adapter.gsa.GSATransaction@1ed902c
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:371)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2586)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.processor.ProcUpdateOrderRepository.runProcess(ProcUpdateOrderRepository.java:
100)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller ....stack trace CROPPED after 10 lines.
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller Caused by
(#2):CONTAINER:atg.commerce.CommerceException: Saving order A100000810
failed because doing so would result in data being overwritten. This
save attempt had an out of date repository item [order].;
SOURCE:atg.repository.ConcurrentUpdateException: no rows updated
oldVersion=45 for item=order:A100000810 in
GSATransaction=atg.adapter.gsa.GSATransaction@1ed902c
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.processor.ProcSaveOrderObject.runProcess(ProcSaveOrderObject.java:
184)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2586)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.processor.ProcUpdateOrderRepository.runProcess(ProcUpdateOrderRepository.java:
100)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller ....stack trace CROPPED after 10 lines.
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller Caused by
(#3):atg.repository.ConcurrentUpdateException: no rows updated
oldVersion=45 for item=order:A100000810 in
GSATransaction=atg.adapter.gsa.GSATransaction@1ed902c
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.adapter.gsa.GSAItemDescriptor.updateItem(GSAItemDescriptor.java:
6072)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.adapter.gsa.GSARepository.updateItem(GSARepository.java:908)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.processor.ProcSaveOrderObject.runProcess(ProcSaveOrderObject.java:
180)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2586)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691 /atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.processor.ProcUpdateOrderRepository.runProcess(ProcUpdateOrderRepository.java:
100)


O'Brien, Paul

unread,
Oct 23, 2008, 4:03:39 PM10/23/08
to atg_...@googlegroups.com
It seems there must be another thread somewhere acting on the repository
item between the time this thread loads the order and the updateOrder()
call. I don't know what process that might be. Maybe there's another
fulfillment thread running? Is someone modifying the order through a
web interface at the same time?

But I don't think the modifications you suggest to
ProcUpdateOrderRepository will help, due to the following:

ProcUpdateOrderRepository is a pipeline processor. The PipelineManager
that invokes the chain manages the transaction. As long as the pipeline
processor has an appropriate "transaction" attribute, as it does OOTB,
there will be a transaction in place when the processor is run.

updateVersion() is called as part of OrderManager.updateOrder(), which
is the method that ProcUpdateOrderRepository calls.

True, there's no synchronization on the order object here. However,
each message to the fulfillment system triggers a process that creates a
new Order object. So synchronizing on a given order object won't help,
since the current thread is the only one that has the given order
object. In the store code, we synchronize because it's possible that
there could be two threads running in the same session that could both
attempt to access the same order object stored in the OrderHolder
component.
185)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691
/atg/commerce/
fulfillment/OrderFulfiller at
atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:
453)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691
/atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2586)
**** Error Wed Oct 22 17:12:23 EDT 2008 1224709943691
/atg/commerce/
fulfillment/OrderFulfiller at
atg.commerce.fulfillment.processor.ProcUpdateOrderRepository.runProcess(
ProcUpdateOrderRepository.java:

Devon Hillard

unread,
Oct 24, 2008, 8:05:55 AM10/24/08
to ATG_Tech
Paul,

the updateOrder method doesn't call updateVersion until after it is
done making the update. If the initial order is out of date, it fails
with an invalid version.

There's also no lock on the user or order rep item or anything, which
might help?

At the time this error happened, and several most just like it, there
was only 1 fulfillment instance running, and no one was using the site
or the web admin. Given the amount of running code in a cluster, it's
very hard to figure out where the order is being accessed at any given
time. Calling updateVersion prior to writing the update seems to make
a lot of this moot.

Thanks!

Devon
> ...
>
> read more »

O'Brien, Paul

unread,
Oct 24, 2008, 2:56:16 PM10/24/08
to atg_...@googlegroups.com
Have you tested calling updateVersion prior to writing the update? I would find it surprising if that worked. updateVersion just makes sure that the version on the Order object in memory is the same as the version in the repository item. The ConcurrentUpdateException is caused by the fact that the version of the repository item in memory is different than the one in the database (because another process updated the item and incremented the value in the database). I don't see how updating the version of the Order object in memory would change that.

You could switch to locked cache-mode for the order item descriptor to see if that helps. If it does, and it doesn't kill your performance, you could go with that.
Reply all
Reply to author
Forward
0 new messages