Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 42676|Răspunde: 4

[Sursă] Gestionarea distincției simultane între Timestamp și ConcurrencyCheck

[Copiază linkul]
Postat pe 08.04.2017 00:10:50 | | | |


Autorwww.itsvse.com @小渣渣 !
Introdu cu succes datele de bază!
Testarea funcției ConcurrencyCheck este finalizată
Actualizare reușită! Notă 1
Actualizarea este excepțională! Notă 2, informații anormale! Instrucțiunea de actualizare, inserare sau ștergere a stocării a afectat un număr neașteptat de rânduri (0). Entitățile pot fi modificate sau șterse de la încărcarea entităților. Consultați http://go.microsoft.com/fwlink/?LinkId=472540 pentru informații despre înțelegerea și gestionarea excepțiilor optimiste de concurență.

Testează diferența dintre Timestamp și ConcurrencyCheck
Actualizare Tab1 reușită! Nume 1
Actualizarea Tab2 a fost reușită! Nume 1
ActualizareActualizarea Tab2 este anormală! Numește 2, informații anormale! Instrucțiunea de actualizare, inserare sau ștergere a stocării a afectat un număr neașteptat de rânduri (0). Entitățile pot fi modificate sau șterse de la încărcarea entităților. Consultați http://go.microsoft.com/fwlink/?LinkId=472540 pentru informații despre înțelegerea și gestionarea excepțiilor optimiste de concurență.
Actualizare Tab1 reușită! Nume 2

【TimeStamp】
Funcția TimeStamp poate fi aplicată clasei câmpului, care are o proprietate de tablou de un singur octet, iar această caracteristică setează tipul tiemStamp pe coloană. În verificările concurente, Code-First folosește automat acest câmp de tip TimeStamp.

【Concurrency Check】
Funcția ConcurrencyCheck poate fi aplicată proprietăților unei clase de domeniu. Când EF efectuează o operație de actualizare, Code-First introduce valoarea coloanei în instrucțiunea condiției where, iar poți folosi această funcție CurrencyCheck pentru a folosi coloanele existente pentru verificarea concurenței, în loc să folosești o coloană TimeStamp separată pentru verificarea concurenței.

Să începem prin a crea un nou obiect de context pentru a demonstra diferența dintre Timestamp și ConcurrencyCheck în procesarea concurenței!

Iată codul pentru context:




Să aruncăm o privire la coloanele bazei de date, după cum urmează:



Vom descoperi că tab1 și tab2 au coloane Id, Nume și Remark, iar tab2 are mai multe coloane RowVersion decât tab1.

Atașează mai întâi codul de test:



【Principiul Verificării Concurenței】



Am adăugat funcția ConcurrencyCheck la proprietatea Remark din Tab1,


Când actualizăm valoarea atributului Name a acelorași date în același timp, nu se face nicio excepție!


Generează instrucțiuni SQL:


executiv sp_executesql N'UPDATE [dbo]. [Tab1]
SET [Nume] = @0
UNDE (([Id] = @1) ȘI ([Remarcă] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1'
executiv sp_executesql N'UPDATE [dbo]. [Tab1]
SET [Nume] = @0
UNDE (([Id] = @1) ȘI ([Remarcă] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1'

Când actualizăm valoarea proprietății Remark a acelorași date în același timp, aruncăm o excepție!

Generează instrucțiuni SQL:

executiv sp_executesql N'UPDATE [dbo]. [Tab1]
SET [Remarcă] = @0
UNDE (([Id] = @1) ȘI ([Remarcă] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note'
executiv sp_executesql N'UPDATE [dbo]. [Tab1]
SET [Remarcă] = @0
UNDE (([Id] = @1) ȘI ([Remarcă] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note'

Putem constata că dacă luăm aceeași bucată de date cu Id 1 în același timp, vom obține valoarea atributului Remark, iar la actualizarea atributului Remark, vom folosi Remark ca condiție de actualizare.

Prima instrucțiune sql poate fi actualizată cu succes, iar apoi remarca este schimbată în "note 1", iar când a doua instrucțiune sql este actualizată, actualizarea va eșua deoarece valoarea remarcii s-a schimbat.

【Principiul Timestamp-ului】

Am adăugat o proprietate RowVersion în Tab2 (poți lua orice nume) și am adăugat funcția Timestamp!



Când actualizăm valoarea Nume a acelorași date în același timp, prima actualizare reușește, a doua eșuează și se aruncă o excepție, hai să aruncăm o privire la codul SQL generat!

executiv sp_executesql N'UPDATE [dbo]. [Tab2]
SET [Nume] = @0
UNDE ((([Id] = @1) ȘI ([RowVersion] = @2)) ȘI ([Remarcă] = @3))
SELECT [RowVersion]
DE la [dbo]. [Tab2]
UNDE @@ROWCOUNT > 0 ȘI [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note'
executiv sp_executesql N'UPDATE [dbo]. [Tab2]
SET [Nume] = @0
UNDE ((([Id] = @1) ȘI ([RowVersion] = @2)) ȘI ([Remarcă] = @3))
SELECT [RowVersion]
DE la [dbo]. [Tab2]
UNDE @@ROWCOUNT > 0 ȘI [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note'

Când rulezi a doua instrucțiune SQL, pentru că datele condiției where nu mai pot fi găsite, actualizarea eșuează și se aruncă o excepție!!

După ce prima instrucțiune sql este executată cu succes, valoarea RowVersion se va schimba, așa cum se arată în figura de mai jos:





RowsVersion este timestamp

Soluție pentru actualizările lipsă   

Conceptul de actualizări lipsă: Când utilizatorii modifică o linie de date în același timp, mai întâi citesc datele, le pun în front-end pentru modificări și apoi trimit datele când sunt modificate, astfel încât datele finale trimise să suprascrie cele trimise anterior, ceea ce duce la pierderea actualizării.

Pe scurt, iată modalități de a preveni pierderea actualizărilor:

Folosește timestamp-ul RowsVersion.

Dacă un rând este inconsistent cu valoarea de dinaintea citirii, înseamnă că o altă tranzacție a actualizat această coloană, astfel încât această coloană nu poate fi actualizată, prevenind astfel pierderea actualizărilor.



În final, atașează codul sursă:
CodeFirstDemo.rar (4.94 KB, Numărul de descărcări: 13)




Precedent:Politica de generare a cheilor primare native Nhibernate
Următor:EF6 folosește Database.BeginTransaction pentru a gestiona tranzacțiile
Postat pe 22.03.2022 11:51:38 |
Mulțumesc pentru munca grea, postare foarte bună
 Proprietarul| Postat pe 01.11.2023 20:42:15 |
Excepția concurenței EF DbUpdateConcurrencyException interoghează valoarea stocată în cache
https://www.itsvse.com/thread-10692-1-1.html
 Proprietarul| Postat pe 27.12.2023 19:54:01 |
Instrucțiuni de migrare generate optimist de blocare EF Core pentru rowversion




Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com