Telerik OpenAccess Classic

Telerik OpenAccess ORM Send comments on this topic.
Optimistic Concurrency Control
Programmer's Guide > OpenAccess ORM Classic (Old API) > Programming With OpenAccess > Concurrency Control > Optimistic Concurrency Control

Glossary Item Box

This documentation article is a legacy resource describing the functionality of the deprecated OpenAccess Classic only. The contemporary documentation of Telerik OpenAccess ORM is available here.

This section describes the algorithm OpenAccess ORM uses for optimistic concurrency control. It presents the concurrency anomalies that are avoided with OpenAccess ORM optimistic concurrency control, and discusses the advantages and the disadvantages of using the OpenAccess ORM optimistic concurrency control.

OpenAccess ORM Optimistic Concurrency Control Algorithm

The database connection and the object scope instance are loosely coupled. This means that the object scope fetches a database connection from the connection pool only if it needs one for a particular operation (e.g., fetching an object) and afterwards returns the connection to the pool. This greatly increases scalability. However there are some operations that lead to a "permanent" coupling between the object scope and database connection that holds until the end of the transaction, thus decreasing scalability. These operations are ITransaction.Flush() and execution of a query with IgnoreUncommitted set to false.

During commit, depending on the mapping present in the backend configuration settings, either the value of a special version column or the values of all the columns of a row are used for a comparing whether a particular row has been changed by another transaction. Only the changed (dirty) objects participate in the comparison during commit. This leads to an isolation level of NO_LOST_UPDATES.

In later releases it will also be possible, to include read but unchanged objects into the comparison, thus making it possible to achieve an isolation level of REPEATABLE_READ.

From the database point of view a single optimistic OpenAccess ORM transaction appears as a series of database transactions. These are usually even on different physical connections. These database transactions only last for a short period of time and all but the last transaction are read-only (unless the operations, ITransaction.Flush() and execution of a query with IgnoreUncommitted set to false are used).

Example:

OpenAccess ORM

Database

begin transaction (ITransaction.Begin())

 

read object A

read object A; commit

read object B

read object B; commit

read and modify object C

read object C; commit

read and modify object D

read object D; commit

commit transaction (ITransaction.Commit())

write objects C and D; commit

In the last step, “write objects C and D” is realized as “UPDATE … SET … WHERE”. The WHERE-clause is used to verify, that no concurrent changes have occurred. As the database transactions are short-lived, it is less important to know how the database backend has implemented its concurrency control algorithms (locking vs. optimistic, versioning vs. non-versioning vs. transaction buffer, waiting locks (with and without deadlock-detection) vs. non-waiting locks.)

The process for setting the isolation level for the database transactions has been described above, in the section discussing pessimistic concurrency control.

Concurrency Anomalies Avoided With OpenAccess ORM Optimistic Concurrency Control

No Lost Updates

Lost updates cannot occur because the version verification for written and deleted objects is always executed. Assume, for example, that a transaction reads an object and continues to run, but a second transaction reads and writes the same object and commits, thus storing a new value for the object. In this case, it is impossible for the first transaction to commit, because the global version counter of the object has been increased during the commit of the second transaction, leading to a verification failure for the first transaction. This is illustrated in this table:

Transaction1

Transaction2

scope1.Transaction.Begin();

scope2.Transaction.Begin();

Customer c = GetCustomerById( 7 );

Customer c = GetCustomerById( 7 );

c.Name = Cooper;

c.DiscountRate = 1.5;

scope1.Transaction.Commit();

 

 

scope2.Transaction.Commit();

With optimistic concurrency control, the Commit() of the scope2.Transaction will throw an OptimisticVerificationException because the version counter column contains a different value when compared to the one read before by transaction 2.

Advantages and Disadvantages of Optimistic Concurrency Control

OpenAccess ORM optimistic concurrency control provides the following advantages:

 

Provides better scalability, as less physical database connections used.

 

Hot spots (objects that are very often requested by many different transactions) can be written, but any other read accesses to the object are aborted when the writer commits.

 

No write locks are applied, so there are no additional client/server calls.

OpenAccess ORM optimistic concurrency control has the following disadvantages:

 

An unnecessary amount of time can pass before a transaction is aborted, even though it is clear, early on, that it will be aborted. The version verification is not executed until the transaction is committed, but a difference in the versions can occur much earlier.

Optimistic concurrency control is useful for long-running transactions that rarely affect the same instances, and therefore the datastore will exhibit better performance by deferring the datastore exclusion on modified instances until commit.