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

读已提交隔离级别下仍存在脏读且偶发主键冲突的问题排查咨询

读已提交隔离级别下仍存在脏读且偶发主键冲突的问题排查咨询

各位大佬好,我现在碰到一个棘手的问题:现有调试中的代码在添加实体时偶尔会触发主键冲突,而且我原本以为读已提交隔离级别能避免脏读,但实际情况却不是这样,想请大家帮忙分析下可能的原因。

先给大家看下核心的伪代码逻辑:

// Controller 方法
await _service.AddOrUpdateAsync(my entity)

// Service/Repository 中的逻辑
using var transaction = await _repository.BeginTransaction() // 内部调用 DbSet.BeginTransactionAsync(IsolationLevel.ReadCommitted)
{
    if (await _repository.Exists(entity primary key field values)) // 内部调用 DbSet.AnyAsync(基于主键字段的查询)
    {
        await _repository.UpdateAsync(my entity) // 内部调用 DbSet.UpdateAsync + Context.SaveChangesAsync()
    }
    else
    {
        await _repository.Add(my entity) // 内部调用 DbSet.AddAsync + Context.SaveChangesAsync()
        // 这里我注意到微软关于DbSet.AddAsync的说明:这个异步方法仅用于特殊值生成器(比如Microsoft.EntityFrameworkCore.Metadata.SqlServerValueGenerationStrategy.SequenceHiLo)需要异步访问数据库的场景,其他情况应该用同步的Add方法
    }
    await transaction.CommitAsync()
}

我现在梳理了几个可能的问题点,想请大家帮忙判断:

  • AddAsync的使用是否不当? 我看到微软文档说AddAsync只针对特定值生成器场景,我这里没有用SequenceHiLo这类策略,是不是应该换成同步的Add方法?会不会因为用了AddAsync导致实体添加的时机出现问题?

  • 依赖注入生命周期不匹配? 我的DI配置是这样的:services.AddDbContext<MyContext>(默认Scoped生命周期),但Service和Repository都是Transient的:services.AddTransient<MyService>、services.AddTransient<MyRepository>。这种上下文是Scoped,而依赖它的服务是Transient的情况,会不会导致多个Repository实例共享或者上下文状态混乱,进而引发并发问题?

  • 隔离级别是否需要调整? 这个API会被两个不同的应用调用(一个是另一个API,一个是控制台程序),偶尔会出现死锁,我知道读已提交隔离级别下死锁是可能发生的,但会不会提升隔离级别(比如可重复读)能解决主键冲突的问题?另外我本地没法复现这个问题,测试起来非常困难。

希望有经验的大佬能给我一些排查思路或者解决方案,谢谢!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 03:08:03