c# - 重复键值违反 SaveChangesAsync 上的唯一约束
问题描述
我在控制器中有以下代码
public async Task<IActionResult> Post(string imei)
{
var device = await _dbContext.Devices.FirstOrDefaultAsync(x => x.Imei == imei);
if (device == null)
{
await _dbContext.Devices.AddAsync(new Device(imei));
await _dbContext.SaveChangesAsync();
}
else
{
throw new ConflictException($"Device with IMEI '{imei}' already exists");
}
return Ok();
}
很难复制,但有时我得到了
23505:重复键值违反唯一约束“devices_imei_key”
似乎它device
是空的,但是当SaveChanges
它已经不为空时。我该如何处理它避免使用try...catch
?我可以AsNoTacking()
用来提高从数据库中读取的能力吗?
解决方案
这是基本的并发,与往常一样,您需要有一个特定的策略来处理并发。您当前使用的方法是不够的,除非您使用信号量对逻辑进行门控,这样一次只能有一个请求通过管道。这避开了并发问题,但显然会对性能产生影响,因为您在应用程序中创建了一个阻塞点。
由于您有唯一的约束,因此您最好的选择是将代码包装在 try/catch 中并实际处理您面临的场景。由于每个 IMEI 应该只有一个条目,因此您可以简单地执行与在 catch 块的 else 块中所做的相同的操作:返回 a ConflictException
。
对于这个特定问题,除了添加锁或处理异常(使用 try/catch)之外没有其他选择。不管你走多“快”,总是有可能发生并发冲突,你需要处理它。
推荐阅读
- erlang - Erlang.mk + boss_db:最小的工作示例
- ruby - 尝试从字符串 RUBY 中删除空格
- node.js - 节点js等待函数返回以继续for循环
- java - 如何写金额
> Corda 中的参数字段? - answer-set-programming - 如何获取谓词中重复值的计数?
- sql-server - 创建更多用于删除记录的 SQL AGENT 步骤是否会带来性能增益或损失
- r - DSN 包含驱动程序和应用程序(Oracle 数据库)之间的体系结构不匹配
- ios - 在表格视图单元格中显示列数据 - 为什么我的表格单元格没有被创建和填充?
- sql-server - 在每个非空值岛中获取最小值
- python - 熊猫数据框是列表列表吗?