Авторwww.itsvse.com @小渣渣 ! Успешно вставьте базовые данные! Тестирование функции ConcurrencyCheck завершено Обновление прошло успешно! Примечание 1 Обновление — это исключительно! Примечание 2, ненормальная информация! Оператор Store Update, insert or delete затронул неожиданное количество строк (0). Сущности могли быть изменены или удалены с момента их загрузки. См. http://go.microsoft.com/fwlink/?LinkId=472540 для получения информации о понимании и работе с оптимистичными исключениями в конкурентности.
Проверьте разницу между Timestamp и Concurrency Check Обновление UpdateTab1 успешно прошло! Название 1 Обновление Tab2 успешно прошло! Название 1 Обновление UpdateTab2 — это ненормально! Имя 2, аномальная информация! Оператор Store Update, insert or delete затронул неожиданное количество строк (0). Сущности могли быть изменены или удалены с момента их загрузки. См. http://go.microsoft.com/fwlink/?LinkId=472540 для получения информации о понимании и работе с оптимистичными исключениями в конкурентности. Обновление UpdateTab1 успешно прошло! Имя 2
【TimeStamp】 Функция TimeStamp может быть применена к классу поля, который обладает только одним свойством массива байтов, и эта функция устанавливает тип tiemStamp для столбца. В параллельных проверках Code-First автоматически использует это поле типа TimeStamp.
【ConcurrencyCheck】 Функция Concurrency Check может быть применена к свойствам класса домена. Когда EF выполняет операцию обновления, Code-First указывает значение столбца в операторе условия where и вы можете использовать эту функцию CurrencyCheck для проверки параллелизма, вместо отдельного столбца TimeStamp для проверки параллелизма.
Давайте начнём с создания нового контекстного объекта, чтобы показать разницу между Timestamp и Concurrency Check в обработке параллелизма!
Вот код контекста:
Давайте рассмотрим столбцы базы данных, а именно так:
Мы увидим, что в tab1 и tab2 есть столбцы Id, Name и Remark, а в tab2 больше столбцов RowVersion, чем в tab1.
Сначала приложите код теста:
【ConcurrencyCheck Principle】
Мы добавили функцию Concurrency Check в свойство Примечания Tab1,
Когда мы обновляем значение атрибута имени для тех же данных одновременно, никаких исключений не возникает!
Генерируйте SQL-операторы:
исполнительный sp_executesql N'UPDATE [DBO]. [Tab1] SET [Имя] = @0 ГДЕ (([Id] = @1) И ([Примечание] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1' исполнительный sp_executesql N'UPDATE [DBO]. [Tab1] SET [Имя] = @0 ГДЕ (([Id] = @1) И ([Примечание] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' Когда мы обновляем значение свойства Renote для тех же данных одновременно, мы создаём исключение!
Генерируйте SQL-операторы:
исполнительный sp_executesql N'UPDATE [DBO]. [Tab1] SET [Примечание] = @0 ГДЕ (([Id] = @1) И ([Примечание] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note' исполнительный sp_executesql N'UPDATE [DBO]. [Tab1] SET [Примечание] = @0 ГДЕ (([Id] = @1) И ([Примечание] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' Мы можем обнаружить, что если взять один и тот же фрагмент данных с Id 1 одновременно, получим значение атрибута Remark, а при обновлении атрибута Remark будем использовать Remark как условие обновления.
Первый sql-оператор можно успешно обновить, затем примечание меняется на «note 1», а при обновлении второго sql-оператора обновление не состоится из-за изменения значения замечания.
【Принцип временной метки】
Мы добавили свойство RowVersion в Tab2 (вы можете взять любое имя) и добавили функцию Timestamp!!
Когда мы обновляем значение имени одних и тех же данных одновременно, первое обновление удаётся, второе — неудачно, и создаётся исключение — давайте посмотрим на сгенерированный sql-код!
исполнительный sp_executesql N'UPDATE [DBO]. [Tab2] SET [Имя] = @0 ГДЕ ((([Id] = @1) И ([RowVersion] = @2)) И ([Примечание] = @3)) SELECT [RowVersion] ОТ [dbo]. [Tab2] ГДЕ @@ROWCOUNT > 0 И [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note' исполнительный sp_executesql N'UPDATE [DBO]. [Tab2] SET [Имя] = @0 ГДЕ ((([Id] = @1) И ([RowVersion] = @2)) И ([Примечание] = @3)) SELECT [RowVersion] ОТ [dbo]. [Tab2] ГДЕ @@ROWCOUNT > 0 И [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' При выполнении второго SQL-оператора, поскольку данные условия where больше не могут быть найдены, обновление не проходит, и создаётся исключение!!
После успешного выполнения первого sql-оператора значение RowVersion изменится, как показано на рисунке ниже:
RowsVersion — это временная метка
Обходной путь для пропущенных обновлений
Концепция отсутствующих обновлений: Когда пользователи одновременно изменяют строку данных, они сначала читают данные, размещают их на интерфейсе для изменений, а затем отправляют данные при изменении, так что окончательные данные перезаписывают ранее заданные, что приводит к потере обновления.
Короче говоря, вот способы избежать потери обновлений:
Используйте временную метку RowsVersion.
Если строка несовместима со значением до чтения, это означает, что другая транзакция обновила этот столбец, и этот столбец нельзя обновить, что предотвращает потерю обновлений.
Наконец, приложите исходный код:
CodeFirstDemo.rar
(4.94 KB, Количество скачиваний: 13)
|