如果多个用户同时在 Blazor 中发出请求会怎样?

Posted

技术标签:

【中文标题】如果多个用户同时在 Blazor 中发出请求会怎样?【英文标题】:What happens if multiple users make a request in Blazor at the same time? 【发布时间】:2021-05-12 08:43:06 【问题描述】:

我实际上只是进入前端和 Blazor,并且正在制作一个简单的 Web 应用程序,该应用程序根据用户输入的数据查询数据库。由于我使用的是 Entity Framework Core,因此我必须小心数据库上下文事务,即同一个 dbcontext 上不能有两个同时事务。

由于与 DB 和 EF Core 一起使用的逻辑位于常规类和方法中,我想知道如果两个用户同时单击前端上的按钮,这是否会启动两个单独的线程,它们将具有两个单独的 dbcontexts 和一切都会好的,或者两个线程(我想它不能只有一个线程,现在是 21 世纪)使用相同的 dbcontext?

为了清楚起见 - 我在启动时使用来自 appsettings.json 的信息创建/实例化我的 dbcontext。我可以改变它没问题,我只需要知道我是否应该。

【问题讨论】:

什么?为什么不能有两个并发事务?数据库将对其进行排序并使其保持原子性和隔离性等。您正在使用TransactionScope对吗?虽然,是的,EF 不是线程安全的,但你可以创建一个新的上下文 @Charlieface, go.microsoft.com/fwlink/?linkid=2097913 正如我所说,使用不同的DbContext。数据库可以处理并发。 @Charlieface,我们似乎误解了对方,因为在我的问题中,我特别谈论了单个 DbContext 的问题。不,我想我们现在明白了。 【参考方案1】:

这取决于 DbContext 在控制器中的作用域。最简单的事情是这样的:

public ActionResult SomeAction( /* params */)

    using (var context = new AppDbContext())
    
        // load and return or update and return data, 
        // preferrably projected ViewModels, not Entities
    

每个请求都使用一个单独的 DbContext。这种方法的主要问题是,单独对控制器进行单元测试更加困难(模拟 DbContext 和 DbSet 很痛苦),并且为您可能想要分散的更大工作流传递 DbContext 可能会很麻烦跨不同的方法或服务。

推荐的模式是依赖注入 /w 一个 IoC 容器,例如 ASP.Net Core 可以原生提供的,或其他类似 Autofac 的模式。在这里,您的控制器接受 DbContext 或包装 DbContext 的工作单元之类的模式,通常作为构造函数参数。从那里开始,取决于如何将 IoC 容器配置为“范围”它提供的 DbContexts 的生命周期。根据容器的不同,有许多选项,但典型的选项是:

单例 - 所有请求的一个实例。 (绝对不是我们想要的 DbContext,因为这将在 Web 请求之间共享相同的引用) 每个 Web 请求 - 每个 Web 请求一个实例。 (推荐) Per Scope - 允许您指定范围边界(小于 Web 请求)并在该范围内返回相同的实例。 每次调用/瞬态 - 在请求时返回一个新实例。 (不推荐,因为来自不同服务的实体在同一个 Web 请求中访问 DbContext 会与不同的 DbContext 相关联。)

【讨论】:

谢谢,我同意你的说法,但问题是当多个用户向服务器发送相同的请求时会发生什么。 @user14092802 他说你应该做什么:每个请求新的 DbContext。发送相同请求的不同用户将彼此独立运行代码,因此您将始终拥有一个新的 DbContext 是的,DbContext 的范围将决定当多个请求进来时会发生什么。每个请求都将由一个工作线程处理,该工作线程处理排队等待空闲请求线程的请求者。使用最简单的示例,这意味着每个请求,即使对于相同的方法,都将获得一个专用的 DbContext。 (安全的)。您需要避免的是任何类型的 static 范围 DbContext,(非常糟糕)或在请求之间缓存/传输实体。 (变得凌乱) @StevePy,啊哈,工作线程的每个请求服务,反过来,根据其范围获得一个 DbContext 是我正在寻找的确切答案,谢谢!

以上是关于如果多个用户同时在 Blazor 中发出请求会怎样?的主要内容,如果未能解决你的问题,请参考以下文章

如何在应用程序中同时处理多个用户请求

在 foreach 循环 Blazor 中触发网络请求

从 Blazor 发出 CORS 请求时如何包含凭据?

Ruby on Rails 同时发出多个 HTTP 请求?

怎样模拟一个并发,多个用户同时请求一个网页

如何与服务器同时处理多个请求