Авторwww.itsvse.com @小渣渣 ! Вставте базові дані успішно! Тестування функції ConcurrencyCheck завершено Оновлення успішно! Примітка 1 Оновлення — виняткове! Примітка 2, аномальна інформація! Оператор Store Update, Insert або Delete впливав на несподівану кількість рядків (0). Сутності могли бути змінені або видалені після їх завантаження. Див. http://go.microsoft.com/fwlink/?LinkId=472540 для отримання інформації про розуміння та поводження з оптимістичними винятками паралелізму.
Перевірте різницю між Timestamp та Concurrency Check Оновлення UpdateTab1 успішне! Назва 1 Оновлення UpdateTab2 успішне! Назва 1 Оновлення Tab2 — це ненормально! Ім'я 2, аномальна інформація! Оператор Store Update, Insert або 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 до властивості Renote у 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!!
Коли ми оновлюємо значення Name для тих самих даних одночасно, перше оновлення проходить успішно, друге — невдале, і з'являється виняток — давайте подивимось на згенерований sql-код!
виконавчий sp_executesql N'UPDATE [dbo]. [Tab2] SET [Ім'я] = @0 ДЕ ((([Id] = @1) ТА ([RowVersion] = @2)) ТА ([Примітка] = @3)) ВИБРАТИ [Версія ряду] ВІД [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)) ВИБРАТИ [Версія ряду] ВІД [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-оператора, оскільки дані умови де більше не можуть бути знайдені, оновлення не завершується, і викидається виняток!!
Після успішного виконання першого sql-оператора значення RowVersion змінюється, як показано на рисунку нижче:
RowsVersion — це часова мітка
Обхідний шлях для відсутніх оновлень
Концепція відсутніх оновлень: Коли користувачі змінюють рядок даних одночасно, вони спочатку читають дані, розміщують їх на фронтенді для зміни, а потім подають дані після зміни, щоб остаточні подані дані перезаписали раніше подані дані, що призводить до втрати оновлення.
Коротко кажучи, ось способи уникнути втрати оновлень:
Використовуйте часову мітку RowsVersion.
Якщо рядок не відповідає значенням до читання, це означає, що інша транзакція оновила цей стовпець, тому цей стовпець не може бути оновлений, що запобігає втраті оновлень.
Нарешті, додайте вихідний код:
CodeFirstDemo.rar
(4.94 KB, Кількість завантажень: 13)
|