.net core - 实时webapi如何处理后续请求中的并发
Dot net core - How does real-time web api handle concurrency in subsequent requests
我正在使用 .net 6 和 entity framework。
这是最常见的情况,当用户在应用程序中注册时,api 检查用户名是否可用,并且仅在用户名可用时才创建帐户。现在假设两个用户同时请求相同的用户名然后两个请求都会发现用户名不可用并且 api 将允许两者都是 created.let 考虑在数据库中创建新用户需要 1 分钟.这怎么能控制。
数据库锁是一种解决方案,但如果我没看错的话,它会对应用程序造成瓶颈。由于这是一个非常常见的场景,我只是好奇如何最好地处理这种情况。
一般的并发问题是两个用户影响数据库中的同一行。
假设我们有一名员工,他的薪水是 3000。
老板给员工加薪,比如说4000,
与此同时,该员工的经理也做了同样的动作,但他将工资提高到 3500。
EF 默认使用乐观并发模式,
所以在这种情况下,最终薪水值将是对该行所做的最后一个操作。
如果 boss 操作首先在 DB 上完成,而 manager 最后完成,那么最终值将为 3500。
问题是经理不知道老板想将员工的工资提高到 4000,他应该了解一些相关信息。
为了防止在 EF 中出现这种情况,您可以使用 ConcurrencyCheck 属性,这样它会在更新之前检查值是否已更改。
[ConcurrencyCheck]
public float Salary{ get; set; }
或使用流利的API
modelBuilder.Entity<Employee>()
.Property(p => p.Salary)
.IsConcurrencyToken();
另一种方法是使用时间戳,但这用于保护整体上的并发问题row/entity。
[Timestamp]
public byte[] ChangeCheck { get; set; }
这是一个特殊的字段,将在数据库中创建为 ROWVERSION,在这种情况下,在 SaveChanges 上将检查 ChangeCheck 的值是否相同。
在您的情况下,同一行没有影响,您只想拥有用户名的唯一值。
您不需要锁定数据库,只需将用户名列标记为 UNIQUE 并为其添加索引以提高性能。
最后一件事是在创建新用户操作时捕获异常并向客户端发送响应。
modelBuilder.Entity<User>()
.HasIndex(p => p.Username)
.IsUnique();
我正在使用 .net 6 和 entity framework。
这是最常见的情况,当用户在应用程序中注册时,api 检查用户名是否可用,并且仅在用户名可用时才创建帐户。现在假设两个用户同时请求相同的用户名然后两个请求都会发现用户名不可用并且 api 将允许两者都是 created.let 考虑在数据库中创建新用户需要 1 分钟.这怎么能控制。
数据库锁是一种解决方案,但如果我没看错的话,它会对应用程序造成瓶颈。由于这是一个非常常见的场景,我只是好奇如何最好地处理这种情况。
一般的并发问题是两个用户影响数据库中的同一行。 假设我们有一名员工,他的薪水是 3000。 老板给员工加薪,比如说4000, 与此同时,该员工的经理也做了同样的动作,但他将工资提高到 3500。 EF 默认使用乐观并发模式, 所以在这种情况下,最终薪水值将是对该行所做的最后一个操作。 如果 boss 操作首先在 DB 上完成,而 manager 最后完成,那么最终值将为 3500。 问题是经理不知道老板想将员工的工资提高到 4000,他应该了解一些相关信息。 为了防止在 EF 中出现这种情况,您可以使用 ConcurrencyCheck 属性,这样它会在更新之前检查值是否已更改。
[ConcurrencyCheck]
public float Salary{ get; set; }
或使用流利的API
modelBuilder.Entity<Employee>()
.Property(p => p.Salary)
.IsConcurrencyToken();
另一种方法是使用时间戳,但这用于保护整体上的并发问题row/entity。
[Timestamp]
public byte[] ChangeCheck { get; set; }
这是一个特殊的字段,将在数据库中创建为 ROWVERSION,在这种情况下,在 SaveChanges 上将检查 ChangeCheck 的值是否相同。
在您的情况下,同一行没有影响,您只想拥有用户名的唯一值。 您不需要锁定数据库,只需将用户名列标记为 UNIQUE 并为其添加索引以提高性能。 最后一件事是在创建新用户操作时捕获异常并向客户端发送响应。
modelBuilder.Entity<User>()
.HasIndex(p => p.Username)
.IsUnique();