With optimistic concurrency, locks are set and held only while a data store is being accessed. These locks prevent other users from updating objects at the same time. An object is unavailable to other sessions while its data is being updated. When an update is attempted, the original version of the changed object is compared against the existing object in the data store. If the two are different, the update fails with a concurrency error. In this instance, it is up to you to figure out how to reconcile the two objects using your business logic.
When creating a persistent object by deriving from the XPBaseObject, XPCustomObject or XPObject class, an OptimisticLockingAttribute is automatically applied. This attribute specifies whether a session can lock a persistent object's state (allow optimistic locking to be enabled). To control object locking for objects that have the object locking option enabled, a new system field (OptimisticLockField) is added to the object table's structure during the database schema update.
The primary purpose of Optimistic Locking is to prevent multiple clients from making modifications to the same object in a database. This is made possible by an optimistic locking field (called OptimisticLockField) that XPO adds to all persistent class tables, except for certain cases (see below). When objects are read from a database, an optimistic locking field is read together with the object content and stored for future use. When a modification is made to an object in a database, the optimistic locking field is checked and if it has been changed, XPO throws a LockingException. If everything is okay, the modification is written to the database and the OptimisticLockField is updated (by default, this field is of an integer type and its value is incremented).
If you derive a persistent class from the XPLiteObject class or use a session-less persistent class, the OptimisticLockingAttribute is not applied. In this instance, you should manually apply this attribute to enable optimistic locking.