Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Concorrenza ottimistica:IsConcurrencyToken e RowVersion

Sia in EF6 che in EF-core, quando si lavora con Sql Server, è necessario utilizzare questa mappatura:

modelBuilder.Entity<Product>() 
.Property(t => t.RowVersion) 
.IsRowVersion(); // Not: IsConcurrencyToken

IsConcurrencyToken configura una proprietà come token di concorrenza, ma (quando la si utilizza per un byte[] proprietà)

  • il tipo di dati è varbinary(max)
  • il suo valore è sempre null se non lo inizializzi
  • il suo valore non viene incrementato automaticamente quando un record viene aggiornato.

Versione IsRow d'altra parte,

  • ha il tipo di dati rowversion (in SQL Server, o timestamp nelle versioni precedenti), quindi
  • il suo valore non è mai nullo e
  • il suo valore viene sempre incrementato automaticamente quando un record viene aggiornato.
  • e configura automaticamente la proprietà in modo che sia un token di concorrenza ottimista.

Ora quando aggiorni un Car vedrai due istruzioni di aggiornamento:

DECLARE @p int
UPDATE [dbo].[Product]
SET @p = 0
WHERE (([Id] = @0) AND ([Rowversion] = @1))
SELECT [Rowversion]
FROM [dbo].[Product]
WHERE @@ROWCOUNT > 0 AND [Id] = @0

UPDATE [dbo].[Car]
SET ...

La prima istruzione non aggiorna nulla, ma incrementa la versione della riga e genererà un'eccezione di concorrenza se la versione della riga è stata modificata nel mezzo.

Il [System.ComponentModel.DataAnnotations.Schema.Timestamp] attributo è l'equivalente delle annotazioni di dati di IsRowVersion() :

[Timestamp]
public byte[] RowVersion { get; set; }