Loading

How Optimistic Locking Works with Persistent Objects

게시 일자: Aug 26, 2025
상세 설명
Customers sometimes face the problem where an order could not be created during the checkout or an order could not be exported via a job. As part of the exception, the following message is written into the error log:
com.demandware.beehive.orm.capi.common.ORMOptimisticLockingException: Optimistic locking failure. Object couldn't be updated.
솔루션
When a thread reads a Persistent Object (PO) from the ORM cache, that thread recognizes its Optimistic Control Attribute (OCA) value. When a thread updates or deletes a PO, the thread uses its UUID and OCA values to identify the PO. That is to say, internally, the WHERE clause of the UPDATE/DELETE operation would include both the UUID and OCA columns as in the following pseudo-SQL:
UPDATE/DELETE ... WHERE UUID='foo' AND OCA=1
In general, optimistic locking failure happens when two threads - no matter what type - attempt to update the PO whose UUID and OCA are the same.

Let's visualize a use case to demonstrate the cause of such optimistic locking failure by using the example of an OrderPO. After an order has been placed, it could look like the following table. The UUID is "foo", the EXPORT_STATUS is NOTEXPORTED, and the OCA is 1. Important here is the OCA value. This is used for the optimistic locking approach and will be incremented when the object gets updated.
 
UUIDEXPORT_STATUSOCA
fooNOTEXPORTED1

Now, let's say we have two threads: thread A is generated via a merchant in the Business Manager who manipulates an order, and thread B is generated by a job which exports orders. Both threads have the same OrderPO from the ORM cache. Now, the merchant changes the EXPORT_STATUS of the order to READY. Thread A identifies the OrderPO whose UUID equals "foo" and OCA equals 1 as described above, and updates its EXPORT_STATUS. At the same time, the OCA is incremented to 2, which results in the following table.
 
UUIDEXPORT_STATUSOCA
fooREADY2

Now, thread B also attempts to update an attribute of the same OrderPO. At this point, ORMOptimisticLockingException will be thrown, because the OCA value has been changed by thread A. The update operation issued by thread B gets a zero row back, because the OrderPO whose UUID equals "foo" and OCA equals 1 does not exist anymore.

This is how optimistic locking works. The Persistent Objects are not locked from the beginning, but they get marked when they are updated. This approach assumes that nothing will be changed while the object is being touched, hence the name, optimistic; it is not a hard lock on the object. On the other hand, pessimistic locking approach locks the object from the beginning, because it assumes that something might be changed while the object is being updated. This approach is used for inventory lists, for instance.
Knowledge 기사 번호

000393690

 
로드 중
Salesforce Help | Article