You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core依赖注入DbContext快速连续点击报线程冲突错误如何解决

问题根因

  1. 静态实例共享DbContext触发并发冲突
    你在RGWIncrementUserActionClicks类中定义了static readonly IncrementSiteActions _IncrementSiteActions、static readonly IncrementUserActions _IncrementUserActions两个静态实例。从报错栈可以看出,IncrementUserActions内部持有独立的DbContext成员,静态实例的生命周期和应用进程一致,这就导致所有请求共用同一个DbContext实例,多请求并发操作时直接触发EF Core的线程安全校验错误。
    你之前的理解误区是认为await会阻塞后续请求,实际上ASP.NET Core是多线程并发处理请求的,每个请求都是独立线程执行,await只能保证单个请求内部的执行顺序,不会阻止服务器处理新的请求,多个请求同时操作静态实例持有的同一个DbContext必然报错。

  2. 前端重复提交触发多请求
    快速连续点击按钮会生成多个独立的HTTP请求,就算修复了DbContext的问题,也会出现重复计数的业务逻辑错误。

修复方案

1. 修正依赖注入逻辑,移除静态实例

所有用到DbContext的业务类都不要使用静态实例,改为注入到DI容器走Scoped生命周期(每个请求一个独立实例):

  • 删除RGWIncrementUserActionClicks、IncrementSiteActions、IncrementUserActions类中的静态实例声明
  • 在Startup.cs中注册三个业务类:
services.AddScoped<RGWIncrementUserActionClicks>();
services.AddScoped<IncrementSiteActions>();
services.AddScoped<IncrementUserActions>();
  • 控制器不再自行newRGWIncrementUserActionClicks,改为构造函数注入:
private readonly RGWIncrementUserActionClicks _rgwIncrementClicks;
private readonly ApplicationDbContext _context;

public RGWController(IEmailSender emailSender, ApplicationDbContext context, RGWIncrementUserActionClicks rgwIncrementClicks)
{
    _emailSender = emailSender;
    _context = context;
    _rgwIncrementClicks = rgwIncrementClicks;
}
  • IncrementSiteActions和IncrementUserActions类改为构造函数注入ApplicationDbContext,不要自行持有静态的DbContext成员。
  • 建议统一SaveChanges调用时机:当前逻辑里IncrementUserActions内部调用一次SaveChangesAsync,UserClick末尾又调用一次,会导致事务拆分,整个业务逻辑执行完统一调用一次即可。

2. 前端增加防重复点击逻辑

点击按钮后立即禁用按钮,等页面跳转后自动重置,从入口避免重复请求,示例代码:

document.querySelector('#click-button').addEventListener('click', function() {
    this.disabled = true;
});

内容的提问来源于stack exchange,提问作者DMur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:30:02