asp.net-mvc 新的 ASP.NET MVC 6 标识中 AspNetUsers 表中的 ConcurrencyStamp 列的用途是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34252640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the purpose of the ConcurrencyStamp column in the AspNetUsers table in the new ASP.NET MVC 6 identity?
提问by Nikolay Kostov
What is the purpose of the ConcurrencyStampcolumn in the AspNetUserstable in the new ASP.NET MVC 6 identity?
新的 ASP.NET MVC 6 标识中表中的ConcurrencyStamp列的用途是什么AspNetUsers?
This is the database schema of the AspNetUserstable:
这是AspNetUsers表的数据库架构:
It is also there in the AspNetRolestable:
它也在AspNetRoles表中:
As I remember it wasn't there in the ASP.NET MVC 5 identity.
我记得它不在 ASP.NET MVC 5 标识中。
What I've noticed so far is that it seems to have GUID values as it is defined with the following code:
到目前为止,我注意到它似乎具有 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();
But this documentation is not sufficient for me to understand in which situations it is used.
但是这个文档不足以让我了解它在哪些情况下使用。
回答by Steven.Xi
As the name state, it's used to prevent concurrency update conflict.
作为名称状态,它用于防止并发更新冲突。
For example, there's a UserAnamed Peter in the database
2 admins open the editor page of UserA, want to update this user.
例如,UserA数据库中有一个叫Peter 2 admins 打开编辑器页面UserA,想更新这个用户。
Admin_1opened the page, and saw user called Peter.Admin_2opened the page, and saw user called Peter (obviously).Admin_1updated user name to Tom, and save data. NowUserAin the db named Tom.Admin_2updated user name to Thomas, and try to save it.
Admin_1打开页面,看到一个叫彼得的用户。Admin_2打开页面,看到用户叫彼得(显然)。Admin_1将用户名更新为 Tom,并保存数据。现在UserA在名为 Tom 的数据库中。Admin_2将用户名更新为 Thomas,并尝试保存它。
What would happen if there's no ConcurrencyStamp is Admin_1's update will be overwritten by Admin_2's update.
But since we have ConcurrencyStamp, when Admin_1/Admin_2loads the page, the stamp is loaded. When updating data this stamp will be changed too.
So now step 5 would be system throw exception telling Admin_2 that this user has already been updated, since he ConcurrencyStampis different from the one he loaded.
如果没有 ConcurrencyStamp 会发生什么情况是 Admin_1 的更新将被 Admin_2 的更新覆盖。但是因为我们有ConcurrencyStamp,当Admin_1/Admin_2加载页面时,邮票被加载。更新数据时,此标记也将更改。所以现在第 5 步是系统抛出异常,告诉 Admin_2 该用户已经更新,因为他ConcurrencyStamp与他加载的用户不同。
回答by Maxime Rouiller
/// <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();
Basically, see it as it is named. A stamp that is used to identify the current version of the data. If you change it, so does the stamp.
基本上,看到它的名字。用于标识数据当前版本的戳记。如果您更改它,则邮票也会更改。
So if two concurrent updates comes in at the same time, they must have the same stamp or one of them should be discarded.
因此,如果同时出现两个并发更新,则它们必须具有相同的标记,否则应丢弃其中一个。
Hence the name, ConcurrencyStamp.
因此得名,ConcurrencyStamp。
回答by mcb
To follow up on Maxime's reply:
跟进马克西姆的回复:
If you look at the implementation of IdentityDbContext in the OnModelCreating() method, you'll find:
如果您查看 OnModelCreating() 方法中 IdentityDbContext 的实现,您会发现:
builder.Entity<TUser>(b =>
{
....
b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();
....
and in the UserStore.UpdateAsync(...)-method:
并在 UserStore.UpdateAsync(...) 方法中:
Context.Update(user);
try
{
await SaveChanges(cancellationToken);
}
catch (DbUpdateConcurrencyException)
{
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}
So, it indeed does what it's supposed to do: prevent concurrent updates on a user object. The token is merely used "under the hood" in the ASP Identity EntityFramework module. Basically, if a concurrent update of one user object occurs, the DB context throws DbUpdateConcurrencyException.
所以,它确实做了它应该做的:防止用户对象的并发更新。该令牌仅在 ASP Identity EntityFramework 模块中“在幕后”使用。基本上,如果发生一个用户对象的并发更新,DB 上下文会抛出 DbUpdateConcurrencyException。
回答by Simon_Weaver
Also important to realize that this is actually a data layer feature. The schema for Identity defines the column as being a concurrency columnbut doesn't actually use it.
同样重要的是要意识到这实际上是一个数据层功能。Identity 的架构将该列定义为并发列,但实际上并未使用它。
There's no logic going on insidethe Identity codebase - it's only when EFCore actually goes to save it that it kicks in.
Identity 代码库内部没有任何逻辑——只有当 EFCore 真正去保存它时,它才会启动。
https://docs.microsoft.com/en-us/ef/core/modeling/concurrency
https://docs.microsoft.com/en-us/ef/core/modeling/concurrency


