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

ASP.NET Core 7 Web API并发投票时如何避免数据更新冲突?

解决ASP.NET Core投票API的并发票数更新问题

问题根源分析

你的代码存在两个核心问题导致并发投票时票数异常:

  1. 自增操作逻辑错误:currVote++是后置自增运算符,会先将currVote的原始值赋值给candidate.VoteCount,再对currVote自增,这意味着实际票数根本没有增加(单线程测试场景下可能未暴露,但本质是逻辑错误)。
  2. 线程安全问题:由于仓储通过AddSingleton注册,多个并发请求会同时访问共享的_candidates集合和候选人对象,导致多个线程同时读取同一个VoteCount值,各自自增后覆盖结果,最终只保留一次自增效果。

修复方案

1. 修正自增逻辑

直接对候选人的VoteCount进行自增操作,避免临时变量带来的错误:

public void VoteCandidate(int id)
{
    Candidate candidate = _candidates.FirstOrDefault(a => a.Id == id);

    if (candidate != null)
    {
        // 直接自增,无需临时变量
        candidate.VoteCount++;
    }
}

2. 添加线程同步保证并发安全

针对Singleton仓储的共享资源访问,有两种常用的线程安全处理方式:

方式一:使用lock语句实现排他访问

在仓储类中定义私有锁对象,确保同一时间只有一个线程能执行票数更新逻辑:

public class VoteRepository
{
    private readonly List<Candidate> _candidates;
    // 定义锁对象
    private readonly object _voteLock = new object();

    public VoteRepository()
    {
        // 初始化候选人数据
        _candidates = new List<Candidate>
        {
            new Candidate { Id = 1, CandidateName = "John Doe", VoteCount = 0 },
            new Candidate { Id = 2, CandidateName = "Max Smith", VoteCount = 0 },
            new Candidate { Id = 3, CandidateName = "Mark Spencer", VoteCount = 0 }
        };
    }

    public void VoteCandidate(int id)
    {
        lock (_voteLock)
        {
            Candidate candidate = _candidates.FirstOrDefault(a => a.Id == id);
            if (candidate != null)
            {
                candidate.VoteCount++;
            }
        }
    }

    // GetCandidateById等其他方法...
}
方式二:使用Interlocked进行原子操作

对于int类型的票数自增,可用Interlocked.Increment实现无锁的原子操作,性能更优:

public void VoteCandidate(int id)
{
    Candidate candidate = _candidates.FirstOrDefault(a => a.Id == id);

    if (candidate != null)
    {
        // 原子性自增,确保多线程下不会丢失更新
        Interlocked.Increment(ref candidate.VoteCount);
    }
}

额外说明

  • 后续引入数据库后,数据库的事务和行级锁(如SQL Server的UPDATE ... WHERE语句)可自动处理并发问题,但当前内存仓储场景必须手动处理线程安全。
  • Blazor WebAssembly端若存在频繁投票场景,建议添加防抖或节流逻辑,减少不必要的并发请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:03:16