[英]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中的工作方式,有两个过程将起作用。
那么这对您来说意味着什么:
//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.