【问题标题】:How does .NET Core handle separate requests at the same time?.NET Core 如何同时处理不同的请求?
【发布时间】:2021-10-28 06:20:55
【问题描述】:

假设我们有一个 API 来订票。控制器方法有两种,一种是检查座位是否已被预订,另一种是预订座位。如果两个用户同时尝试预订同一个座位,那么第一种方法将允许预订座位。它现在将如何处理座位预订,在多个线程中并行运行请求?

【问题讨论】:

  • 一旦座位被预订,您的 api 将阻止该座位。因此,任何对该方法的调用都将返回错误/阻塞或剩余如果您还有很多剩余。
  • 您可以为此使用锁定机制(例如乐观锁定)。
  • 听起来像是某种竞争条件。理论上,所有线程都将争夺同一个席位。让预订系统线程安全可能值得考虑。
  • 如果你想获得技术,还要考虑单个操作系统线程仍然可以使用协程处理多个同时请求(即async await 用于 IO)。虽然是的,但 ASP.NET Core 使用了多种技术,包括 IIS 在HTTP.SYS 中未充分记录的 voodoo、.NET 的线程池(IIS 使用较低的默认线程堆栈大小顺便说一句,因此它可以拥有比正常更多的线程)和异步 IO。
  • 对您的问题的快速、简短和简单的回答是,您的持久性存储(通常是 SQL RDBMS)将负责确保事务正确性 :它将自行处理事务(前提是您正确使用BEGIN TRANSACTIONCOMMIT)。否则你的数据库状态将被破坏(实际上所有主要的 RDBMS 都能很好地处理这个问题,你只需要注意你是否自己做 IO,就像你正在写入一个简单的文本文件或类似文件一样)。

标签: c# asp.net-core webrequest


【解决方案1】:

假设我们有一个 API 来订票。

好的...

有两种控制器方法,一种检查座位是否已被预订,另一种用于预订座位。

到目前为止,一切正常。

如果两个用户同时尝试预订同一个座位,那么第一种方法将允许预订座位。

这完全取决于您的底层预订服务的持久性存储如何处理并发请求。

  • 如果您使用的是 SQL 数据库(MS SQL、MySQL、Oracle、PostgreSQL 等),那么您需要将您的 SQL 代码的 critical section 包装在 TRANSACTION 语句中,并在末尾加上 COMMIT,这样,RDBMS 将为您处理the ACID-compliance
    • 例如,上述所有 RDMBS 都会让对不同不相关行的并发 IO 并行发生,因为没有冲突,但是如果两个单独的 SQL 事务会影响相同的行,它们将“顺序化”操作,这就是它们的方式确保符合 ACID。
    • 如果您使用的是实体框架,那么不幸的是它会更复杂,因为 EF 不会生成单个长 SQL 语句批处理:它(通常)在 C#/.NET 代码和 SQL 之间执行单个语句和乒乓球,所以您需要小心。出于这个原因,使用 PROCEDURE 而不是让 EF 这样做很重要(而且通常更简单)。
  • 如果您使用的是进程内内存,则无需使用lock 语句来保护临界区,以及适当地使用并发安全集合(如ConcurrentDictionary)。
    • System.Collections.Concurrent 类型并不神奇(它们应该重命名为“减少锁定集合”imo),您仍然需要了解它们的工作原理以及它们做什么和不做什么(没有 @例如 987654330@ 类型 - 想想why that is)。
  • 如果您使用其他外部服务作为后端,则无需担心,因为处理并发操作是他们的问题。
    • 除非您使用的外部服务不提供任何方式事务正确,在这种情况下,您需要在自己的代码中限制并发操作,这不会轻松扩展(因为内存技术速度很快,但当您的应用程序部署在多个 Web 服务器上时不起作用)。

现在如何处理座位预订,在多个线程中并行运行请求?

这是您要处理的问题,而不是 ASP.NET 的问题。

【讨论】:

  • 事务本身解决不了任何问题。预订系统是需要应用程序逻辑的东西,实际上无论是在代码中还是在程序中。 ORM 将愉快地首先保存用户 1 的预订,然后保存用户 2 对相同座位和日期的预订。 ORM 确实支持更新的并发性,例如时间戳与 WHERE ConcurrencyStamp = @PreviousStamp 结合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-19
  • 2017-03-01
  • 2021-08-21
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
相关资源
最近更新 更多