首先插入外键记录以避免竞争条件?



我有4张表

Table1 (primary)
Id
Table2 (foreign 1)
Id
Table1Id
Table3 (foreign 2)
Id
Table1Id

表1可以有一个没有表2、表3和表4的记录。

现在我们有许多记录添加到这些表中,我们的应用程序根据表1中的id进行读取以构造响应。

您通常会先添加表1中的记录,然后添加表2和表3等。

我们的问题是,我们的轮询(每30秒运行一次)应用程序从表1中选择id,但未能从表2、3和4中获取链接记录,因为应用程序在保存表1中的记录后,试图在链接记录保存到表2、3和4之前获取。

有办法防止这种情况发生吗?我们可以先保存外键记录吗?这样,直到所有链接的记录都保存在表2和表3中,应用程序才会看到表1中的记录。这是一种普遍和安全的做法吗?

任何建议都会很好!

提前谢谢你

根据您的系统设计,您可能总是有这种竞争条件。例如,在一个web应用程序中,如果你有一个页面允许你添加一个TableA,保存它,然后点击一个按钮来输入相关的TableB,那么在一段时间内,对TableA的查询将收到一个不完整的表示。

解决方案是,要么设计系统,要么设计数据,使其始终可以被指望表明数据处于完整状态。例如,用户可以创建整个对象图,而不是设计成独立保存关系中的逐页实体。实体框架使用导航属性来管理关系,因此,如果客户端流程遍历捕获表a的数据,然后是相关的表B和C等,然后将所有这些细节传递到要持久化的结构中,则可以使用单个"保存";通过一次调用SaveChanges,一次性创建相关实体的操作。这确保了所有实体一起提交,或者根本不提交。(如果有例外)EF可以确保表以正确的顺序填充,并在需要时分配fk。你不需要"保存"。a TableA获取它的ID以填充到TableB中:

var tableA = new TableA
{
Name = viewModel.Name,
TableB = new TableB
{
Name = viewModel.BsName,
// ... or use biewModel.BDetails.Name, etc.
},
TableC = new TableC
{
// ....
}
};
context.TableAs.Add(tableA);
context.SaveChanges();  // Saves the A, B, and related C, etc.

如果数据相当大且复杂,并且尝试一次捕获所有内容是没有意义的,例如,如果在记录状态被认为足够完整以进行查询之前,数据可能需要在相当长的一段时间内输入,用户必须积累或检查数据等,那么您可以考虑在顶级表上使用类似Status的东西。(表a)这可能是一个类似枚举的东西。当您最初创建TableA记录时,状态将默认为"inprogress"之类的东西。任何查询报告或此类查看tablea的查询都只知道查询状态为"complete"的记录。当用户输入他们的Table B、C等时,将会有一个自动验证或手动断言来确定TableA记录是否可以被标记为"完成",从而更新状态。从那时起,报表/摘要查询视图将开始在结果中看到这一行。

最新更新