让我们有一个带有ID和名称的假想表foo.我们对Web应用程序执行2个并行请求.这两个请求都会处理一些逻辑,然后作为此逻辑的一部分,将按名称判断表(foo.name==quest.name).如果数据库中不存在此条目,请创建它.

如果2个请求试图创建具有相同名称的相同条目,但只能存在一个这样的条目,您会如何处理呢?下面是说明问题的伪代码.

Process(Request request) 
{
    // some logic that takes around 3000ms
    
    var foo = context.Foos.SingleOrDefault(f => f.Name == request.Name)

    if (foo == null)
    {
        context = new Foo { Name = request.Name }
        context.Foos.Add(foo)
    }
    
    car.Foo = foo;
    context.Cars.Add(car);
    context.SaveChanges()
} 

推荐答案

您应该确保判断具有给定名称的Foo是否存在,如果不存在,则创建它.

您可以使用具有锁定机制的数据库事务:

Process(Request request) 
{
    using (var dbContextTransaction = context.Database.BeginTransaction()) 
    {
        try
        {
            // Some logic

            var foo = context.Foos.SingleOrDefault(f => f.Name == request.Name);

            if (foo == null)
            {
                foo = new Foo { Name = request.Name };
                context.Foos.Add(foo);
            }
            
            car.Foo = foo;
            context.Cars.Add(car);
            context.SaveChanges();

            dbContextTransaction.Commit();
        }
        catch (Exception)
        {
            dbContextTransaction.Rollback();
            throw;
        }
    }
} 

.net相关问答推荐

为什么Linq中的运算符逻辑不匹配结果,当值为0或在VB. NET中没有

EFCore.DbSet.Update 方法添加新行而不是更新它

在数据网格中:如何在更改单元格 A 中的值后显示单元格 B 中的更改

是否有内置方法将 nuget 包引用为 csproj 中的文件?

AppShell - 返回导航失败,匹配的路由不明确......但我只注册了一次路由

更改列表中的值

为什么(真的吗?)List 实现所有这些接口,而不仅仅是 IList

单击关闭按钮时隐藏表单而不是关闭

Int32.ToString() 是特定于文化的吗?

XmlNode 值与内部文本

注册 COM 互操作与使程序集 COM 可见

如何通过 LINQ 比较没有时间的 DateTime?

使用只读属性或方法?

.NET 如何判断路径是否是文件而不是目录?

在 .NET Core RC2 中构建 .exe 文件

如何将 System.Type 转换为其可为空的版本?

将字典值转换为数组

如何过滤具有多个条件的 Directory.EnumerateFiles?

了解 C# 中的协变和逆变接口

模拟和单元测试需要时如何抛出 SqlException?