Web 应用程序 - 如何同步处理来自用户的事件?

问题描述 投票:0回答:1

我有 Blazor Interactive Server 应用程序。在我的几个页面上,我有一个组件,用户可以在其中注册活动。有 4 个按钮(否、未定、有兴趣、参加)。当他们单击按钮时,会触发一个事件,从数据库读取 2 条记录,使用注册状态更新它们,然后保存它们。

用户快速点击几个按钮(不知道为什么)。最终结果是我收到一个 DbUpdateConcurrencyException,因为它读取多个事件处理程序调用中的记录,更新它们,然后保存它们,并且在第一次抛出 DbUpdateConcurrencyException 之后进行所有操作。

有没有办法强制每个会话同步处理此事件处理程序?涉及的记录是用户记录,因此会话之间不会发生冲突,除非用户通过 2 个浏览器连接并同时单击 - 在这种情况下很难。

blazor blazor-server-side
1个回答
0
投票

听起来这里的问题实际上与数据库在组件中的连接方式有关。您是否将 DbContext 注入到组件中,然后在整个组件中使用相同的实例?

如果是这样,这将是问题的原因。

在 Blazor 中,注入服务的范围仅限于电路的生命周期(与更传统的 Web 应用程序中的请求生命周期相反)。 DbContexts 不允许在您看到的同一实例上并发工作。

Microsoft 的建议是每个操作都应该有一个 DbContext 实例(而不是组件的公共实例)。

实现这一点的方法是在组件中注入一个DbContextFactory,然后就可以轻松创建实例了。

@inject IDbContextFactory<ContactContext> DbFactory

private async Task Undecided()
{
   // create a DbContext that is scoped to just this action
   using var context = DbFactory.CreateDbContext();

   // do DB stuff here

   await context.SaveChangesAsync();
}

private async Task Interested()
{
   using var context = DbFactory.CreateDbContext();

   // do DB stuff here

   await context.SaveChangesAsync();
}

您可以在这里阅读更多相关信息:

https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-ef-core?view=aspnetcore-8.0#new-dbcontext-instances

© www.soinside.com 2019 - 2024. All rights reserved.