5.3.11 Logical Data Locking

Data locking is an important component of rigorous maintenance applications. This locking is often implemented primarily at the physical level, which is important and works well for the short database transactions that occur in milliseconds. But when used across long business transactions, they tie up far too much data and are complex and error prone. AOA uses physical database locking, but only at the end of an object commit, when a database transaction is started and held during all the inserts, updates and deletes that are defined in the object, after which the transaction is immediately ended.

For handling locking across a long business transaction, AOA provides two options: pessimistic locking and optimistic locking. In addition, the structure and meta-information of the object minimizes locking needs in general, while also providing the foundation that enables optimistic locking.

It is desirable to start by looking at the structural characteristics of an AOA object that impact locking. On the right is shown part of the mCourse object, the object in OpenCUAS used for maintaining course information. Though the object is composed of many entities, it is contended here that it is usually only necessary to put a lock on the root, the Course entity, itself. This is based on three observations.

  1. There is no need to lock any of the display entities, those shown in gray in the example, as they are only read as part of the mCourse object and never updated. (In fact, as noted earlier, they cannot be updated based on the permission rules.)
  2. There is also no need to lock any of the included entities, those shown in yellow in the example, as they are only included as a part of this object, meaning only foreign keys are created pointing to them. Their data content remains unchanged.
  3. Surprisingly, there is also no need to lock the created/updated entities, CourseTopic and CoursePrerequisiteGroup. That is because their content is unique to their parent entity, Course, and is not shared by any other mCourse object.

That means to lock the root entity, Course, is to lock any of the variable content within the object. Though there are a few exceptions, the above is true for the vast majority of cases. AOA provides the ability to also lock subordinate entities in those exceptional cases.

Pessimistic Locking

Pessimistic locking assumes it is fairly likely that two functions will try to update an object at the same time. Thus, when an object is “activated for update”, a logical lock must be created to make sure the second function can’t get hold of the object for update while the first function still has it. Note that there need not be any restriction for someone to read the same instance of the object at the same time, as reading alone creates no conflict.

In AOA, pessimistic locking is triggered by requesting to activate an object for update. If someone else tries to activate this same object for update, an error is returned to the user, though a read-only version of the object is still activated into memory. Activate for update is initiated by simply adding one parameter, SingleForUpdate, to the ACTIVATE operation.

The logical lock in AOA is implemented by writing a locking record to the database, which is released when the object is dropped.

Optimistic Locking

Optimistic locking assumes it is unlikely that two functions will try to update an object at the same time. Thus, no lock is issued at activate to keep that from happening. Instead, to protect against duplicate update, a copy of the current content of the object is saved at activate. Then, at the commit of the object, the content of the original state of the object for any of its updatable data is compared to the corresponding values in the database and if any of those values have changed, the commit is aborted.