, ,

A collision is said to occur when two activities, which may or may not be full-fledged transactions, attempt to change entities within a system of record.  There are three fundamental ways (Celko 1999) that two activities can interfere with one another:

  1. Dirty read.  Activity 1 (A1) reads an entity from the system of record and then updates the system of record but does not commit the change (for example, the change hasn’t been finalized). Activity 2 (A2) reads the entity, unknowingly making a copy of the uncommitted version. A1 rolls back (aborts) the changes, restoring the entity to the original state that A1 found it in. A2 now has a version of the entity that was never committed and therefore is not considered to have actually existed.
  2. Non-repeatable read.  A1 reads an entity from the system of record, making a copy of it. A2 deletes the entity from the system of record. A1 now has a copy of an entity that does not officially exist.
  3. Phantom read.  A1 retrieves a collection of entities from the system of record, making copies of them, based on some sort of search criteria such as “all customers with first name Bill.”A2 then creates new entities, which would have met the search criteria (for example, inserts “Bill Klassen” into the database), saving them to the system of record. If A1 reapplies the search criteria it gets a different result set.

Locking Strategies:

2.1 Pessimistic Locking

Pessimistic locking is an approach where an entity is locked in the database for the entire time that it is in application memory (often in the form of an object).  A lock either limits or prevents other users from working with the entity in the database.  A write lock indicates that the holder of the lock intends to update the entity and disallows anyone from reading, updating, or deleting the entity.  A read lock indicates that the holder of the lock does not want the entity to change while the hold the lock, allowing others to read the entity but not update or delete it.  The scope of a lock might be the entire database, a table, a collection of rows, or a single row.  These types of locks are called database locks, table locks, page locks, and row locks respectively.The advantages of pessimistic locking are that it is easy to implement and guarantees that your changes to the database are made consistently and safely.  The primary disadvantage is that this approach isn’t scalable.  When a system has many users, or when the transactions involve a greater number of entities, or when transactions are long lived, then the chance of having to wait for a lock to be released increases.  Therefore this limits the practical number of simultaneous users that your system can support.

2.2 Optimistic Locking

With multi-user systems it is quite common to be in a situation where collisions are infrequent.  Although the two of us are working with Customer objects, you’re working with the Wayne Miller object while I work with the John Berg object and therefore we won’t collide.  When this is the case optimistic locking becomes a viable concurrency control strategy.  The idea is that you accept the fact that collisions occur infrequently, and instead of trying to prevent them you simply choose to detect them and then resolve the collision when it does occur.

Figure 1 depicts the logic for updating an object when optimistic locking is used.  The application reads the object into memory.  To do this a read lock is obtained on the data, the data is read into memory, and the lock is released.  At this point in time the row(s) may be marked to facilitate detection of a collision (more on this later).  The application then manipulates the object until the point that it needs to be updated.  The application then obtains a write lock on the data and reads the original source back so as to determine if there’s been a collision.  The application determines that there has not been a collision so it updates the data and unlocks it.  Had a collision been detected, e.g. the data had been updated by another process after it had originally been read into memory, then the collision would need to be resolved.

Ways to use above : versioning and session cache in Hibernate