Authorwww.itsvse.com @小渣渣 ! Insert the base data successfully! Testing the ConcurrencyCheck feature is complete Update successful! Note 1 Update is exceptional! Note 2, abnormal information! Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
Test the difference between Timestamp and ConcurrencyCheck UpdateTab1 update successful! Name 1 UpdateTab2 update successful! Name 1 UpdateTab2 update is abnormal! Name 2, abnormal information! Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions. UpdateTab1 update successful! Name 2
【TimeStamp】 The TimeStamp feature can be applied to the field class, which has only one byte array property, and this feature sets the tiemStamp type to the column. In concurrent checks, Code-First automatically uses this TimeStamp type field.
【ConcurrencyCheck】 The ConcurrencyCheck feature can be applied to the properties of a domain class. When EF performs an update operation, Code-First puts the value of the column in the where condition statement, and you can use this CurrencyCheck feature to use the existing columns for concurrency checking, rather than using a separate TimeStamp column for concurrency checking.
Let's start by creating a new context object to demonstrate the difference between Timestamp and ConcurrencyCheck in concurrency processing!
Here's the code for the context:
Let's take a look at the columns of the database, as follows:
We will find that tab1 and tab2 have Id, Name, and Remark columns, and tab2 has more RowVersion columns than tab1.
Attach the test code first:
【ConcurrencyCheck Principle】
We added the ConcurrencyCheck feature to the Remark property of Tab1,
When we update the Name attribute value of the same data at the same time, no exception is thrown!
Generate SQL statements:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Name] = @0 WHERE (([Id] = @1) AND ([Remark] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1' exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Name] = @0 WHERE (([Id] = @1) AND ([Remark] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' When we update the Remark property value of the same data at the same time, we throw an exception!
Generate SQL statements:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Remark] = @0 WHERE (([Id] = @1) AND ([Remark] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note' exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Remark] = @0 WHERE (([Id] = @1) AND ([Remark] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' We can find that if we take the same piece of data with Id 1 at the same time, we will get the value of the Remark attribute, and when updating the Remark attribute, we will use Remark as the update condition.
The first sql statement can be updated successfully, and then the remark is changed to "note 1", and when the second sql statement is updated, the update will fail because the value of the remark has changed.
【Timestamp Principle】
We added a RowVersion property to Tab2 (you can take any name) and added the Timestamp feature!!
When we update the Name value of the same data at the same time, the first update succeeds, the second update fails, and an exception is thrown, let's take a look at the generated sql code!
exec sp_executesql N'UPDATE [dbo]. [Tab2] SET [Name] = @0 WHERE ((([Id] = @1) AND ([RowVersion] = @2)) AND ([Remark] = @3)) SELECT [RowVersion] FROM [dbo]. [Tab2] WHERE @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note' exec sp_executesql N'UPDATE [dbo]. [Tab2] SET [Name] = @0 WHERE ((([Id] = @1) AND ([RowVersion] = @2)) AND ([Remark] = @3)) SELECT [RowVersion] FROM [dbo]. [Tab2] WHERE @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' When executing the second SQL statement, because the data of the where condition can no longer be found, the update fails and an exception is thrown!!
After the first sql statement is successfully executed, the value of RowVersion will change, as shown in the figure below:
RowsVersion is timestamp
Workaround for missing updates
Concept of missing updates: When users modify a line of data at the same time, they first read the data, put it on the front end for modification, and then submit the data when modified, so that the final submitted data will overwrite the previously submitted data, which causes the lost update.
Long story short, here are ways to prevent losing updates:
Use the RowsVersion timestamp.
If a row is inconsistent with the value before reading, it means that another transaction has updated this column, so that this column can not be updated, thus preventing the loss of updates.
Finally, attach the source code:
CodeFirstDemo.rar
(4.94 KB, Number of downloads: 13)
|