Optimistic Concurrency Control
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
This topic deals with optimistic concurrency control.
You can discover whether data has changed on the server while a user is in the process of editing the same data in a number of ways:
- Using Timestamp for Concurrency Checks
-
Using DateTime Column for Concurrency Check
- Using Version Number for Concurrency Check
- Checking for Any Changes
Using Timestamp for Concurrency Checks
The simplest mechanism for detecting that anything in a database row has changed is to use a timestamp (also known as rowversion) field. A timestamp is a binary field that is automatically updated whenever changes are made to any columns in the row. Many databases have a specific data type that is used for this. SQL Server uses the timestamp data type. With databases that do not have an explicit rowversion type, patterns are available for creating triggers to update fields in your database.
If you use timestamps field in your database, you have to bring them on the surface as properties in your entities. Telerik Data Access will map the timestamp column to a Int64 property in your object.
Telerik Data Access will automatically detect the mapped timestamp column and will set the persistent type concurrency mode to backend.
For example, consider the following case. Suppose, you have a timestamp column in your table in the database.
When you reverse map your table, Telerik Data Access will automatically map the timestamp column to a Int64 property in your object. The Concurrency Member for the generated entity will be automatically set to that property and the Concurrency Mode will be set to Backend.
In case your domain model is already generated, you don't have to re-generate it. Just use the Update Model from Database Wizard.
Using DateTime Column for Concurrency Check
In case your database legacy does not allow you to use timestamp column, you could use a DateTime column to detect concurrent updates. The time of the operation is set on every insert or update, and the previous value is included in the where clause. This may not be safe if updates happen quicker than the resolution of the time field.
For example, consider the following case. Suppose, you have a DateTime column in your table in the database.
And you have updated your domain model, so the DateTime column is included in the model. In contrast to the timestamp column, the datetime column could not be automatically detected as a version property. That's why you have to set the Concurrency Mode/Member for your entity manually. To do that:
- Select the entity in the Visual Designer.
- Press F4 to open the Property Window.
- Set the Concurrency Mode property to Timestamp.
- Set the Concurrency Member to your DateTime property.
Each time the record is updated, the datetime column will be updated automatically by Telerik Data Access.
Using Version Number for Concurrency Check
You could use a version column to detect concurrent updates. Usually the data type for the column is int. The version number is incremented on every update and the previous version number is included in the where clause. This is the fastest and safest optimistic concurrency control mode.
For example, consider the following case. Suppose, you have an int column in your table in the database (on the snapshot below, this is the Counter column).
After you update your domain model, you have to set the Concurrency Mode property for the target entity to Version, and set the the Counter property (the version column) as a Concurrency Member.
Checking for Any Changes
In case your database schema does not allow you any modifications (adding a version column for example), you could check for any changed columns. For example, if you set the Concurrency Mode to Changed, then all changed columns will be included in the where clause. This provides you more fine-grained optimistic concurrency control as different transactions may modify different fields of the same instance. Float and double fields are excluded as they are not exact (rounding procedures are different across databases and also differ from the way .NET is handling it).
If you set the Concurrency Mode to All, then the values of all columns (changed or not) will be included in the where clause.