Для чего нужно поле ConcurrencyStamp таблицы AspNetUsers в identity?

190
08 февраля 2020, 23:40

Внимание! Это перевод вопроса What is the purpose of the ConcurrencyStamp column in the AspNetUsers table in the new ASP.NET MVC 6 identity?

Для чего нужно поле ConcurrencyStamp таблицы AspNetUsers в identity?

Вот структура таблицы AspNetUsers в базе:

Такое же поле есть и в таблице AspNetRoles:

Насколько я помню, такого поля не было в ASP.NET MVC 5 identity, появилось в MVC 6.

Вижу, что в это поле пишется GUID следующим кодом:

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

Но документации недостаточно для меня, чтобы понять в каких ситуациях оно используется.

Answer 1

Судя по названию, поле используется, чтобы предотвратить конфликт одновременного обновления записи.

Например, есть пользователь UserA в базе по имени Peter и два администратора открывают страницу редактирования пользователя UserA, чтобы обновить ему данные.

  1. Admin_1 открыв страницу видит имя пользователя Peter.
  2. Admin_2 открыв страницу видит имя пользователя (разумеется).
  3. Admin_1 сменил имя пользователя на Tom и сохранил данные. Сейчас UserA в базе имеет имя Tom.
  4. Admin_2 сменил имя пользоватля на Thomas и пытается сохранить.

В случае без поля ConcurrencyStamp обновление первого (Admin_1) администратора было бы перезаписано обновлением второго (Admin_2).

Но поскольку у нас есть поле, то когда Admin_1/Admin_2 загружаются страницу, загружается и штамп записи. При обновлении данных записи сохраняется и штамп.

Теперь шаг 5 будет состоять в том, что система выкинет исклюение говоряющее второму администратору (Admin_2) что этот пользователь уже был обновлён, так как ConcurrencyStamp отличается от сохранённого в базе.

Примечание переводчика. В соседнем ответе напоминают, что проверку конкурентного обновления можно включить для любой таблицы, указав это через аннотации или fluent api:

Data Annotations

public class Person
{
    public int PersonId { get; set; }
    [ConcurrencyCheck]
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

Fluent API

class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .Property(p => p.LastName)
            .IsConcurrencyToken();
    }
}
public class Person
{
    public int PersonId { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
}

На русском языке об этом упоминается например в статье на metanit

READ ALSO
Не работает ImageSource.FromStream Xamarin Forms

Не работает ImageSource.FromStream Xamarin Forms

Нужно загрузить картинку с использованием HttpClientНо нижеприведенный код не работает

193
Как называется класс, у которого все поля (свойства) открытые

Как называется класс, у которого все поля (свойства) открытые

Яркий пример - модели в том же EntityFramework наNET

150
Как сделать снимок экрана в WPF? Есть код на Windows Forms, нужно перенести на WPF

Как сделать снимок экрана в WPF? Есть код на Windows Forms, нужно перенести на WPF

У меня есть небольшой участок кода на Winforms ,который я хочу перенести на WPFНужно получить картинку своего экрана

145
Сворачивание приложения в трей

Сворачивание приложения в трей

Допустим есть программа которая фоном делает определенные операции, не важно какие, допустим каждые 10 секунд собирает информацию по нагрузке...

166