c# - 异步合理性检查会导致出现竞争条件吗?
问题描述
我有一个使用 EF Core 的 .Net 5 Web API 项目,并考虑了我的业务处理程序的数据一致性。我个人认为这个问题与技术无关,也适用于其他 Web 框架。以下只是一个例子(设计可能不好)
想象一下 API 提供了两个端点
POST /users/{userId}/documents/{documentId}
将用户链接到文档DELETE /users/{userId}
删除用户
数据库持有一个交叉表
用户 | 文档 |
---|---|
用户 1 | 文件1 |
用户 1 | 文档2 |
用户 2 | 文档2 |
将用户链接到文档的逻辑可能看起来像
var user = await FetchUserFromDb(userId);
if(user == null)
{
return new NotFoundResponse($"user {userId} not found");
}
var document = await FetchDocumentFromDb(documentId);
if(document == null)
{
return new NotFoundResponse($"document {documentId} not found");
}
var insertResult = await InsertIntoCrossTable(userId, documentId);
return new CreatedResponse(insertResult);
删除用户的逻辑可能看起来像
var affectedRows = await DeleteUserFromDb(userId);
if(affectedRows == 0)
{
return new NotFoundResponse($"user {userId} not found");
}
return new NoContentResponse("user deleted successfully");
目前,我不知道如果两个请求同时进来会发生什么。POST 请求将成功返回用户,然后尝试从数据库中检索文档。如果此时用户被删除,POST 请求中的业务逻辑将不再意识到这一点。插入查询语句将引发数据库异常,因为用户的外键不再存在。
我在这里错了吗,请求一个接一个地处理?还是我作为开发人员必须专门处理这个问题(通过为数据库异常添加额外的 try/catch 语句)?
解决方案
Or do I as a developer have to deal with this issue specifically (by adding additional try/catch statements for database exceptions)?
You do have to deal with it some way. Either:
- Extend your transaction to include both the select and the insert, or
- Handle the exception (either with retries that will also retry the select or returning an error code), or
- Don't handle the exception and let the user/UI refresh on error.
what if my data source is not a database?
That's an impossibly broad question. So the answer is also broad: "use whatever concurrency techniques are recommended for your data source."
推荐阅读
- node.js - EACCES : PM2 使用命令 `npm run ...`
- node.js - 同步 Lambda 和 SNS 集成
- ruby - ruby 2.7 和更早的代码是否与 ruby 3.0.1 兼容?
- groovy - Groovy $getCallSiteArray 实现
- android - RecyclerView 测试滚动到位置
- python - 我可以运行多个 DataFrame 并将一个函数应用于每个列表吗?
- python - Cffi 和 char** 作为参数
- python - 从另一个文件导入 Python 会引发错误
- java - 将抽象类作为参数类型传递,无法覆盖方法。我对java中的多态性有误解吗?
- flutter - 如何在另一个类中使用吸气剂?