web-dev-qa-db-ja.com

新しいASP.NET MVC 6 IDのAspNetUsersテーブルのConcurrencyStamp列の目的は何ですか?

新しいASP.NET MVC 6 IDのConcurrencyStampテーブルのAspNetUsers列の目的は何ですか?

これは、AspNetUsersテーブルのデータベーススキーマです。

enter image description here

AspNetRolesテーブルにもあります。

enter image description here

覚えているように、ASP.NET MVC 5 IDにはありませんでした。

私がこれまで気づいたことは、次のコードで定義されているように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();

しかし、このドキュメントでは、どの状況で使用されているかを理解するには不十分です。

41
Nikolay Kostov

名前の状態として、並行性更新の競合を防ぐために使用されます。

たとえば、データベース2にPeterという名前のUserAがいて、管理者2人がUserAのエディターページを開いて、このユーザーを更新したいとします。

  1. Admin_1はページを開き、Peterというユーザーを確認しました。
  2. Admin_2がページを開き、Peter(明らかに)というユーザーを見ました。
  3. Admin_1はユーザー名をTomに更新し、データを保存しました。これで、Tomという名前のデータベース内のUserA。
  4. Admin_2はユーザー名をThomasに更新し、保存しようとしました。

ConcurrencyStampがない場合、Admin_1の更新はAdmin_2の更新によって上書きされます。しかし、ConcurrencyStampがあるため、Admin_1/Admin_2がページをロードすると、スタンプがロードされます。データを更新すると、このスタンプも変更されます。したがって、ステップ5は、ConcurrencyStampがロードしたものとは異なるため、このユーザーが既に更新されていることをAdmin_2に通知するシステムスロー例外です。

54
Steven.Xi

ソースコード自体から

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

基本的に、名前が付けられているとおりに表示します。データの現在のバージョンを識別するために使用されるスタンプ。変更すると、スタンプも変更されます。

したがって、2つの同時更新が同時に発生した場合、それらは同じスタンプを持っているか、そのうちの1つを破棄する必要があります。

したがって、名前はConcurrencyStampです。

12
Maxime Rouiller

Maximeの返信をフォローアップするには:

OnModelCreating()メソッドでIdentityDbContextの実装を見ると、次のことがわかります。

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

そして、UserStore.UpdateAsync(...)-メソッドで:

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

したがって、実際に行うべきことを実行します。ユーザーオブジェクトの同時更新を防止します。トークンは、ASP Identity EntityFrameworkモジュールで「内部」で使用されます。基本的に、1つのユーザーオブジェクトの同時更新が発生すると、DBコンテキストはDbUpdateConcurrencyExceptionをスローします。

5
mcb

また、これが実際にEF Core機能であることを理解することも重要です。Identityのスキーマは、同時実行列として使用される列を定義するだけですが、最終的にはそれを必要とせず、内部で使用しません。

比較ロジックはありませんinsideIdentity codebase-EFCoreが実際にそれを保存するときだけが起動します。

https://docs.Microsoft.com/en-us/ef/core/modeling/concurrency

EFコードファースト-IsConcurrencyToken()

4
Simon_Weaver