gpt4 book ai didi

c# - Entity Framework 线程安全创建实体(如果不存在)

转载 作者:太空宇宙 更新时间:2023-11-03 10:53:26 31 4
gpt4 key购买 nike

我想编写一个方法,将一个实体插入到我的数据库中(如果它尚不存在)。我希望它在许多服务器上都是线程安全的。所以实际上,它必须在数据库级别是并发安全的。这可能与 Entity Framework 有关吗?还是我必须使用原始 SQL 执行此操作?

这是我目前所拥有的:

public void CreateFooIfDoesntExist(int bar)
{
using (var dbContext = new MyDbContex())
{
if (!dbContext.Set<Foo>().Any(f => f.Bar == bar))
{
//Not thread safe because two servers could both fail to find any
//Foos at the same time. Then they'd both try to add a Foo.
dbContext.Set<Foo>().Add(new Foo { Bar = bar });
dbContext.SaveChanges();
}
}
}

我正在使用 C# 5.0、EF 5.0 和 MSSQL 服务器 2012。

最佳答案

您可以创建一个唯一索引,因此第二次保存将始终失败并显示众所周知的错误代码。问题是,您需要一个字段而不是自动生成的 ID 来创建唯一索引。

try
{
using (var context ...)
{
context.Foos.Add(new Foo() { UniqueId = id });
context.SaveChanges();
}
}
catch (UpdateException e)
{
// record with "id" already exists
}

在更复杂的场景中,您可以使用数据库事务来同步多个进程。当您在具有 SERIALIZABLE 隔离级别的事务中执行数据库更新时,SQL Server 将锁定您更新的行。在第一个进程结束事务之前,此锁将阻止任何其他进程写入数据,甚至禁止读取数据。所以你基本上在你的模式中有一个锁列/行/表。每当您需要执行全局操作时,您将启动一个事务并更新锁,然后执行您需要执行的任何其他工作。在第一个进程结束事务之前,任何竞争进程都无法读取/更新您的锁。

关于c# - Entity Framework 线程安全创建实体(如果不存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20436976/

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