21

Qual è lo scopo della colonna ConcurrencyStamp nella tabella AspNetUsers nella nuova identità di ASP.NET MVC 6?Qual è lo scopo della colonna ConcurrencyStamp nella tabella AspNetUsers nella nuova identità di ASP.NET MVC 6?

Questo è lo schema del database della tabella AspNetUsers:

enter image description here

E 'anche lì nella tabella AspNetRoles:

enter image description here

Come mi ricordo che non era lì in l'identità di ASP.NET MVC 5.

Quello che ho notato finora è che sembra avere valori GUID come viene definito con il seguente codice:

/// <summary> 
/// A random value that must change whenever a user is persisted to the store 
/// </summary> 
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString(); 

Ma questa documentazione non è sufficiente per me per capire in quali situazioni è Usato.

+2

I_assume_ (non ho ancora usato v6), che come suggerisce il nome, è usato per gestire gli 'aggiornamenti' concomitanti su un' utente'. _manuale_ aggiungo qualcosa di simile (ad esempio 'rowversion' /' timestamp') a [realizza lo stesso] (http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/movimentazione-concorrenza-con-la-entità-quadro-in-un-asp-net-mvc-applicazione). Hth ... – EdSF

+0

Sto iniziando a pensare che questo sia per scopi di caching di ASP.NET. –

+0

Quello che voglio sapere è, perché l'hanno impostato su 'nvarchar (MAX)' se non sarà più lungo di un GUID –

risposta

6

From the source code itself

/// <summary> 
    /// A random value that should change whenever a role is persisted to the store 
    /// </summary> 
    public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString(); 

In sostanza, lo vedono come prende il nome. Un timbro che viene utilizzato per identificare la versione corrente dei dati. Se lo cambi, lo fa anche il timbro.

Quindi, se due aggiornamenti simultanei arrivano nello stesso momento, devono avere lo stesso timbro o uno di essi deve essere scartato.

Da cui il nome, ConcurrencyStamp.

+0

l'ho già trovato. Vedi la mia domanda. –

+0

ha aggiunto più informazioni. scusa. mancanza di caffeina. –

2

dare seguito alla risposta di Maxime:

Se si guarda l'attuazione IdentityDbContext nel metodo OnModelCreating(), troverete:

builder.Entity<TUser>(b => 
{ 
.... 
    b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken(); 
.... 

e nel UserStore.UpdateAsync (. ..) - metodo:

Context.Update(user); 
    try 
    { 
     await SaveChanges(cancellationToken); 
    } 
    catch (DbUpdateConcurrencyException) 
    { 
     return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure()); 
    } 

Quindi, lo fa davvero quello che si suppone di fare: impedire aggiornamenti simultanei su un oggetto utente. Il token è semplicemente usato "sotto la cappa" nel modulo ASP Identity EntityFramework. In sostanza, se si verifica un aggiornamento simultaneo di un oggetto utente, il contesto DB lancia DbUpdateConcurrencyException.

20

Come stato del nome, viene utilizzato per impedire conflitti di aggiornamento della concorrenza.

Ad esempio, c'è un utente di nome Peter nella banca dati 2 amministratori aprono la pagina di editor di UtenteA, vogliono aggiornare questo utente.

  1. Admin_1 ha aperto la pagina e ha visto l'utente chiamato Peter.
  2. Admin_2 ha aperto la pagina e l'utente ha chiamato Peter (ovviamente).
  3. Admin_1 nome utente aggiornato su Tom e salvataggio dei dati. Ora UtenteA nel db chiamato Tom.
  4. Admin_2 nome utente aggiornato su Thomas e prova a salvarlo.

Cosa succederebbe se non ci fosse ConcurrencyStamp L'aggiornamento di Admin_1 verrà sovrascritto dall'aggiornamento di Admin_2. Ma dal momento che abbiamo ConcurrencyStamp, quando Admin_1/Admin_2 carica la pagina, viene caricato il timbro. Quando si aggiornano i dati, anche questo timbro verrà modificato. Quindi ora il passaggio 5 sarebbe un'eccezione di lancio del sistema che dice a Admin_2 che questo utente è già stato aggiornato, poiché ConcurrencyStamp è diverso da quello che ha caricato.

Problemi correlati