Forfatterwww.itsvse.com @小渣渣 ! Sett inn grunndataene på en vellykket måte! Testing av ConcurrencyCheck-funksjonen er fullført Oppdatering vellykket! Notat 1 Oppdateringen er eksepsjonell! Notat 2, unormal informasjon! Store-oppdatering, innsetting eller delete-setningen påvirket et uventet antall rader (0). Entiteter kan ha blitt endret eller slettet siden entiteter ble lastet inn. Se http://go.microsoft.com/fwlink/?LinkId=472540 for informasjon om forståelse og håndtering av optimistiske samtidighetsunntak.
Test forskjellen mellom Timestamp og ConcurrencyCheck UpdateTab1-oppdatering vellykket! Navn 1 UpdateTab2-oppdateringen vellykket! Navn 1 UpdateTab2-oppdateringen er unormal! Navn 2, unormal informasjon! Store-oppdatering, innsetting eller delete-setningen påvirket et uventet antall rader (0). Entiteter kan ha blitt endret eller slettet siden entiteter ble lastet inn. Se http://go.microsoft.com/fwlink/?LinkId=472540 for informasjon om forståelse og håndtering av optimistiske samtidighetsunntak. UpdateTab1-oppdatering vellykket! Navn 2
【TimeStamp】 TimeStamp-funksjonen kan brukes på feltklassen, som kun har én byte-array-egenskap, og denne funksjonen setter tiemStamp-typen til kolonnen. Ved samtidige kontroller bruker Code-First automatisk dette TimeStamp-typen.
【ConcurrencyCheck】 ConcurrencyCheck-funksjonen kan brukes på egenskapene til en domeneklasse. Når EF utfører en oppdateringsoperasjon, legger Code-First verdien til kolonnen i where-betingelsessetningen, og du kan bruke denne CurrencyCheck-funksjonen til å bruke de eksisterende kolonnene for samtidighetssjekk, i stedet for å bruke en separat TimeStamp-kolonne for samtidighetskontroll.
La oss starte med å lage et nytt kontekstobjekt for å demonstrere forskjellen mellom Timestamp og ConcurrencyCheck i samtidighetsbehandling!
Her er koden for konteksten:
La oss se på kolonnene i databasen, som følger:
Vi vil finne at tab1 og tab2 har kolonnene Id, Name og Remark, og tab2 har flere RowVersion-kolonner enn fane 1.
Legg ved testkoden først:
【ConcurrencyCheck Principle】
Vi la til ConcurrencyCheck-funksjonen i Remark-egenskapen til Tab1,
Når vi oppdaterer Navn-attributtverdien for de samme dataene samtidig, kastes ingen unntak!
Generer SQL-setninger:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SETT [Navn] = @0 HVOR (([Id] = @1) OG ([Merknad] = @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] SETT [Navn] = @0 HVOR (([Id] = @1) OG ([Merknad] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' Når vi oppdaterer Remark-egenskapsverdien for samme data samtidig, kaster vi et unntak!
Generer SQL-setninger:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SETT [Merk] = @0 HVOR (([Id] = @1) OG ([Merknad] = @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] SETT [Merk] = @0 HVOR (([Id] = @1) OG ([Merknad] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' Vi kan finne at hvis vi tar samme databit med ID 1 samtidig, får vi verdien av Merk-attributtet, og når vi oppdaterer Merk-attributtet, bruker vi Merk-attributt som oppdateringsbetingelse.
Den første SQL-setningen kan oppdateres med suksess, og deretter endres kommentaren til «note 1», og når den andre SQL-setningen oppdateres, vil oppdateringen feile fordi verdien av kommentaren har endret seg.
【Tidsstempelprinsippet】
Vi la til en RowVersion-egenskap i Tab2 (du kan ta hvilket som helst navn) og la til Timestamp-funksjonen!!
Når vi oppdaterer navneverdien til de samme dataene samtidig, den første oppdateringen lykkes, den andre oppdateringen feiler, og et unntak kastes, la oss se på den genererte SQL-koden!
exec sp_executesql N'UPDATE [dbo]. [Tab2] SETT [Navn] = @0 HVOR ((([Id] = @1) OG ([RowVersion] = @2)) OG ([Merknad] = @3)) VELG [RowVersion] FRA [dbo]. [Tab2] HVOR @@ROWCOUNT > 0 OG [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binær(8),@3 nvarchar(max) ',@0=N'Navn1',@1=1,@2=0x00000000000007D1,@3=N'Note' exec sp_executesql N'UPDATE [dbo]. [Tab2] SETT [Navn] = @0 HVOR ((([Id] = @1) OG ([RowVersion] = @2)) OG ([Merknad] = @3)) VELG [RowVersion] FRA [dbo]. [Tab2] HVOR @@ROWCOUNT > 0 OG [id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binær(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' Når man kjører den andre SQL-setningen, fordi dataene fra where-betingelsen ikke lenger kan finnes, feiler oppdateringen og et unntak kastes!!
Etter at den første SQL-setningen er utført med suksess, vil verdien av RowVersion endres, som vist i figuren nedenfor:
RowsVersion er tidsstempel
Løsning på manglende oppdateringer
Konseptet med manglende oppdateringer: Når brukere endrer en linje med data samtidig, leser de først dataene, legger dem på frontenden for endring, og sender deretter inn dataene når de er endret, slik at de siste innsendte dataene vil overskrive de tidligere innsendte dataene, noe som fører til tapt oppdatering.
For å gjøre en lang historie kort, her er måter å unngå å miste oppdateringer på:
Bruk tidsstempelet RowsVersion.
Hvis en rad er inkonsistent med verdien før lesingen, betyr det at en annen transaksjon har oppdatert denne kolonnen, slik at denne kolonnen ikke kan oppdateres, og dermed forhindres tap av oppdateringer.
Til slutt, legg ved kildekoden:
CodeFirstDemo.rar
(4.94 KB, Antall nedlastinger: 13)
|