gpt4 book ai didi

c# - 在 Entity Framework 核心中执行业务规则

转载 作者:太空狗 更新时间:2023-10-29 20:29:47 24 4
gpt4 key购买 nike

假设我有一个执行以下操作的 Controller 操作:

  1. 检查在特定时间是否有日历槽
  2. 检查是否没有与该时间段重叠的已预订约会
  3. 如果两个条件都满足,它会在给定时间创建一个新约会

简单的实现带来了多个问题:

  • 如果在步骤 3 之前删除了在 1 中获取的日历槽怎么办?
  • 如果在第 2 步之后但在第 3 步之前预约了另一个约会怎么办?

这些问题的解决方案似乎是使用 SERIALIZABLE 事务隔离级别。问题是每个人似乎都认为这种事务隔离级别非常危险,因为它可能会导致死锁。

给出以下简单的解决方案:

public class AController
{
// ...
public async Task Fn(..., CancellationToken cancellationToken)
{
var calendarSlotExists = dbContext.Slots.Where(...).AnyAsync(cancellationToken);
var appointmentsAreOverlapping = dbContext.Appointments.Where(...).AnyAsync(cancellationToken);
if (calendarSlotExists && !appointmentsAreOverlapping)
dbContext.Appointments.Add(...);
dbContext.SaveChangesAsync(cancellationToken);
}
}

始终防止并发问题的最佳方法是什么?我应该如何处理最终的死锁?

最佳答案

数据库完整性检查是你最好的 friend

根据您的描述,您的约会是基于时段的。这使问题变得简单得多,因为您可以有效地为 Appointments 表上的 SlotId 定义唯一约束。然后你需要一个用于 Appointments.SlotId 引用的外键 Slot.Id

what if the calendar slot fetched in 1 is removed before step 3?

数据库会抛出外键违规异常

what if another appointment is booked after step 2 but before step 3?

数据库会抛出重复键异常

接下来您需要做的是捕获这两个异常并将用户重定向回预订页面。再次从数据库重新加载数据并检查是否有无效条目,通知用户进行修改并重试。

对于死锁部分,它实际上取决于您的表结构。你访问数据的方式,你索引它们的方式,以及 DB 的查询计划。对此没有明确的答案。

关于c# - 在 Entity Framework 核心中执行业务规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55343663/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com