Autorewww.itsvse.com @小渣渣 ! Inserisci con successo i dati di base! Il test della funzione ConcurrencyCheck è completato Aggiornamento riuscito! Nota 1 L'aggiornamento è eccezionale! Nota 2, informazioni anomale! L'istruzione aggiornamento, inserimento o cancellazione store ha influenzato un numero inaspettato di righe (0). Le entità potrebbero essere state modificate o eliminate da quando le entità sono state caricate. Consulta http://go.microsoft.com/fwlink/?LinkId=472540 per informazioni su come comprendere e gestire le eccezioni di concorrenza ottimistica.
Verifica la differenza tra Timestamp e ConcurrencyCheck Aggiornamento Tabella1 con successo! Nome 1 Aggiornamento Tabella2 aggiornamento riuscito! Nome 1 L'aggiornamento di Tabella2 è anomalo! Nomina 2, informazioni anomale! L'istruzione aggiornamento, inserimento o cancellazione store ha influenzato un numero inaspettato di righe (0). Le entità potrebbero essere state modificate o eliminate da quando le entità sono state caricate. Consulta http://go.microsoft.com/fwlink/?LinkId=472540 per informazioni su come comprendere e gestire le eccezioni di concorrenza ottimistica. Aggiornamento Tabella1 con successo! Nome 2
【Timestamp】 La funzione TimeStamp può essere applicata alla classe di campo, che ha una sola proprietà di byte nell'array, e questa caratteristica imposta il tipo tiemStamp sulla colonna. Nei controlli concorrenti, Code-First utilizza automaticamente questo campo di tipo TimeStamp.
【Concurrency Check】 La funzione ConcurrencyCheck può essere applicata alle proprietà di una classe di dominio. Quando EF esegue un'operazione di aggiornamento, Code-First inserisce il valore della colonna nell'istruzione condizione where, e puoi usare questa funzione CurrencyCheck per utilizzare le colonne esistenti per il controllo della concorrenza, invece di usare una colonna TimeStamp separata per il controllo della concorrenza.
Iniziamo creando un nuovo oggetto contesto per dimostrare la differenza tra Timestamp e ConcurrencyCheck nell'elaborazione della concorrenza!
Ecco il codice per il contesto:
Diamo un'occhiata alle colonne del database, come segue:
Scopriremo che tab1 e tab2 hanno colonne Id, Nome e Nota, e tab 2 ha più colonne RowVersion rispetto a tab1.
Allega prima il codice di test:
【Principio di Concurrency Check】
Abbiamo aggiunto la funzione ConcurrencyCheck alla proprietà Commentazione di Tab1,
Quando aggiorniamo il valore dell'attributo Name degli stessi dati nello stesso momento, non viene fatta alcuna eccezione!
Genera istruzioni SQL:
executive sp_executesql N'UPDATE [dbo]. [Tabula 1] SET [Nome] = @0 DOVE (([Id] = @1) E ([Osservazione] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1' executive sp_executesql N'UPDATE [dbo]. [Tabula 1] SET [Nome] = @0 DOVE (([Id] = @1) E ([Osservazione] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' Quando aggiorniamo il valore della proprietà Remark degli stessi dati nello stesso momento, facciamo un'eccezione!
Genera istruzioni SQL:
executive sp_executesql N'UPDATE [dbo]. [Tabula 1] SET [Osservazione] = @0 DOVE (([Id] = @1) E ([Osservazione] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note' executive sp_executesql N'UPDATE [dbo]. [Tabula 1] SET [Osservazione] = @0 DOVE (([Id] = @1) E ([Osservazione] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' Possiamo scoprire che se prendiamo lo stesso dato con Id 1 nello stesso momento, otterremo il valore dell'attributo Remark, e quando aggiorniamo l'attributo Remark, useremo Remark come condizione di aggiornamento.
La prima istruzione sql può essere aggiornata con successo, poi la nota viene cambiata in "nota 1", e quando la seconda istruzione sql viene aggiornata, l'aggiornamento fallirà perché il valore della nota è cambiato.
【Principio di Timestamp】
Abbiamo aggiunto una proprietà RowVersion a Tab2 (puoi prendere qualsiasi nome) e la funzione Timestamp!!
Quando aggiorniamo il valore Name degli stessi dati contemporaneamente, il primo aggiornamento ha successo, il secondo fallisce e viene lanciata un'eccezione, diamo un'occhiata al codice SQL generato!
executive sp_executesql N'UPDATE [dbo]. [Tabula 2] SET [Nome] = @0 DOVE ((([Id] = @1) E ([RowVersion] = @2)) E ([Osservazione] = @3)) SELECT [RowVersion] DA [dbo]. [Tabula 2] DOVE @@ROWCOUNT > 0 E [Id] = @1',N'@0 nvarchar(max), @1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note' executive sp_executesql N'UPDATE [dbo]. [Tabula 2] SET [Nome] = @0 DOVE ((([Id] = @1) E ([RowVersion] = @2)) E ([Osservazione] = @3)) SELECT [RowVersion] DA [dbo]. [Tabula 2] DOVE @@ROWCOUNT > 0 E [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' Quando esegui la seconda istruzione SQL, poiché i dati della condizione where non si trovano più, l'aggiornamento fallisce e viene lanciata un'eccezione!!
Dopo che la prima istruzione sql è stata eseguita con successo, il valore di RowVersion cambierà, come mostrato nella figura sottostante:
RowsVersion è il timestamp
Soluzione alternativa per gli aggiornamenti mancanti
Concetto di aggiornamenti mancanti: quando gli utenti modificano una riga di dati contemporaneamente, prima leggono i dati, li mettono nel frontend per la modifica e poi li inviano quando vengono modificati, così che i dati finali inviati sovrascrivano quelli precedentemente inviati, causando l'aggiornamento perso.
Per farla breve, ecco modi per evitare di perdere aggiornamenti:
Usa il timestamp di RowsVersion.
Se una riga è incoerente con il valore prima della lettura, significa che un'altra transazione ha aggiornato questa colonna, quindi questa colonna non può essere aggiornata, prevenendo così la perdita degli aggiornamenti.
Infine, allega il codice sorgente:
CodeFirstDemo.rar
(4.94 KB, Numero di download: 13)
|