Concurrency Handling in LightSwitch
LightSwitch automatically detects concurrency conflicts, but you can improve the performance of an application in some cases by understanding how LightSwitch handles that process .
Problems can occur in applications when multiple users are allowed to edit the same record at the same time. Applications that detect concurrency conflicts first determine whether another user has changed a record, and they handle any conflicting values appropriately.
LightSwitch uses the OData protocol for communication between the client and server. The OData protocol uses the ETag part of the HTTP protocol to detect concurrency conflicts. Every property that will be used to detect concurrency conflicts has its original value serialized into the ETag value when the item is read. This value is sent to the client application along with all other values of the entity that's being read. A client that tries an update will submit the ETag value along with the updated property values to the server. The server will verify whether the ETag still matches the original value. If the value has changed, the update is rejected, and the application must handle the conflict.
LightSwitch handles conflicts slightly differently depending on what data source is being used.
When you create a table in the LightSwitch intrinsic database, a generated column that's named RowVersion is added to your table. The RowVersion column utilizes the rowversion data type in SQL Server. The rowversion column is automatically updated each time that any other column in the record is updated. Rather than serializing all column values into an Etag, only the 8-byte value in RowVersion is used to detect conflicts. This strategy helps to improve performance by reducing the amount of data that's sent to the server.
You can’t display the RowVersion column in the Entity Designer, but that column appears in the Screen Designer. You can write code for the RowVersion column by using the RowVersion_Changed, RowVersion_IsReadOnly, and RowVersion_Validate methods.
You can also create a query in the Query Designer by using RowVersion. For example, you might want to detect whether a record has been changed since the most recent time that it was read. To detect such changes, you can create a query with Id and RowVersion parameters. You can pass in a record’s Id and current RowVersion values into the parameters of this query. If no record is returned, the record has been modified or deleted. If a record is returned, the record hasn't changed in the database.
When you connect to an existing database in LightSwitch and a rowversion column exists in a table, LightSwitch uses that rowversion column to detect concurrency conflicts. If you attach to an external database that doesn’t contain a rowversion column, Visual Studio LightSwitch uses all available columns to detect concurrency conflicts. The latter strategy could result in poor performance, especially with large sets of data.
We recommend that you add a rowversion column to external database tables, which you can do by using SQL Server Management Studio or the SQL Server Object Explorer in Visual Studio.
When you attach to a Windows Communication Foundation (WCF) Rich Internet Application (RIA) data source, LightSwitch uses one of three attributes of WCF RIA Services to determine whether a property should be used to detect concurrency conflicts: TimestampAttribute, ConcurrencyCheckAttribute, or RoundTripOriginalAttribute. Any property that's marked with one of these attributes on your WCF RIA entity is used to detect concurrency conflicts. If the entity doesn’t have any of these attributes on its properties, all properties are used to detect concurrency conflicts. The latter strategy could result in poor performance, especially with large sets of data.