tutorial net mvc framework example español crear asp and asp.net-mvc concurrency database-schema identity asp.net-core-mvc

asp.net-mvc - net - login entity framework c# mvc



¿Cuál es el propósito de la columna ConcurrencyStamp en la tabla AspNetUsers en la nueva identidad ASP.NET MVC 6? (3)

¿Cuál es el propósito de la columna ConcurrencyStamp en la tabla AspNetUsers en la nueva identidad ASP.NET MVC 6?

Este es el esquema de base de datos de la tabla AspNetUsers :

También está allí en la tabla de AspNetRoles :

Según recuerdo, no estaba allí en la identidad ASP.NET MVC 5.

Lo que he notado hasta ahora es que parece tener valores GUID como se define con el siguiente código:

/// <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();

Pero esta documentación no es suficiente para que pueda entender en qué situaciones se utiliza.


Como estado del nombre, se utiliza para evitar conflictos de actualización de concurrencia.

Por ejemplo, hay un UserA llamado Peter en la base de datos. 2 administradores abren la página del editor de UserA, quieren actualizar este usuario.

  1. Admin_1 abrió la página, y vio al usuario llamado Peter.
  2. Admin_2 abrió la página y vio al usuario llamado Peter (obviamente).
  3. Admin_1 actualizó el nombre de usuario a Tom y guardó los datos. Ahora UserA en la db llamada Tom.
  4. Admin_2 actualizó el nombre de usuario a Thomas e intenta guardarlo.

Lo que sucedería si no hay ConcurrencyStamp es que la actualización de Admin_1 será sobrescrita por la actualización de Admin_2. Pero ya que tenemos ConcurrencyStamp, cuando Admin_1 / Admin_2 carga la página, se carga el sello. Al actualizar los datos este sello también se cambiará. Así que ahora el paso 5 sería una excepción de lanzamiento del sistema que le dice a Admin_2 que este usuario ya se ha actualizado, ya que ConcurrencyStamp es diferente de la que cargó.


Para seguir la respuesta de Maxime:

Si observa la implementación de IdentityDbContext en el método OnModelCreating (), encontrará:

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

y en el método UserStore.UpdateAsync (...):

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

Entonces, efectivamente hace lo que se supone que debe hacer: evitar actualizaciones concurrentes en un objeto de usuario. El token se usa simplemente "debajo del capó" en el módulo EntityFramework de identidad de ASP. Básicamente, si se produce una actualización simultánea de un objeto de usuario, el contexto de la base de datos emite la excepción DbUpdateConcurrencyException.


Desde el propio código fuente.

/// <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();

Básicamente, verlo como se llama. Un sello que se utiliza para identificar la versión actual de los datos. Si lo cambias, también lo hace el sello.

Entonces, si dos actualizaciones simultáneas llegan al mismo tiempo, deben tener el mismo sello o una de ellas debe ser descartada.

De ahí el nombre, ConcurrencyStamp .