繁体   English   中英

EF数据库并发

[英]EF database concurrency

我有两个应用程序:一个应用程序是asp.net,另一个是在后台运行的Windows服务。

在后台运行的Windows服务正在数据库上执行某些任务(读取和更新),而用户可以通过asp.net应用程序对数据库执行其他操作。 因此,我很担心,例如,在Windows服务中,我收集了一些满足条件的记录,然后对它们进行迭代,例如:

IQueryable<EntityA> collection = context.EntitiesA.where(<condition>)
foreach (EntityA entity in collection)
{
  // do some stuff
}

因此,如果用户修改了在循环迭代中稍后使用的记录,那么EF会考虑该记录的哪个值? 执行时检索到的原始文件:

context.EntitiesA.where(<condition>)

还是由用户修改并位于数据库中的新数据库?

据我所知,在迭代过程中,EF是按需获取的每条记录,我的意思是,一个接一个地读取,因此当读取下一个记录的下一个迭代时,该记录对应于从以下位置收集的记录:

context.EntitiesA.where(<condition>)

还是位于数据库中的那个(用户刚刚修改的那个)?

谢谢!

关于这在EF中的工作方式,有两个过程将起作用。

  1. 查询仅在枚举时执行(有时称为查询实现),此时将执行整个查询
  2. 在上面的示例中,延迟加载仅影响导航属性。 where语句的结果集将被一次性下拉。

那么这对您来说意味着什么:

//nothing happens here you are just describing what will happen later to make the 
// query execute here do a .ToArray or similar, to prevent people adding to the sql 
// resulting from this use .AsEnumerable
IQueryable<EntityA> collection = context.EntitiesA.where(<condition>); 
//when it first hits this foreach a 
//SELECT {cols} FROM [YourTable] WHERE [YourCondition] will be performed
foreach (EntityA entity in collection)
{
    //data here will be from the point in time the foreach started (eg if you have updated during the enumeration in the database you will have out of date data)
    // do some stuff
}

如果您真的担心会发生这种情况,请DbContext获取ID的列表,并使用每个ID的新DbContext单独处理它们(或者说每10个批次之后)。 就像是:

IList<int> collection = context.EntitiesA.Where(...).Select(k => k.id).ToList();
foreach (int entityId in collection)
{
    using (Context context = new Context())
    {
        TEntity entity = context.EntitiesA.Find(entityId);
        // do some stuff
        context.Submit();
    }
}

我认为您的问题的答案是“取决于情况”。 您所描述的问题称为“不可重复读取”,可以通过设置适当的事务隔离级别来防止发生该问题。 但这会带来性能损失和潜在的僵局。

有关更多详细信息,请阅读此内容

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM