Entity framework 实体框架6、事务范围、上下文和保存更改
问题与事务范围和Entity framework 实体框架6、事务范围、上下文和保存更改,entity-framework,entity-framework-6,transactionscope,savechanges,Entity Framework,Entity Framework 6,Transactionscope,Savechanges,问题与事务范围和context.SaveChanges()有关。如果我使用foreach处理一百万条记录,并且在事务范围内调用context.SaveChanges()每次保存1000条记录,并且在处理10000条记录并调用SaveChanges()后出现故障,那么是否已经回滚保存的数据? 例如: 只要注册了DbContext,事务范围优先,默认情况下是这样 因此,如果您不调用TransactionScope.Complete(例如,因为与DbContext相关的异常将您抛出使用块的),所有内容
context.SaveChanges()
有关。如果我使用foreach
处理一百万条记录,并且在事务范围内调用context.SaveChanges()
每次保存1000条记录,并且在处理10000条记录并调用SaveChanges()
后出现故障,那么是否已经回滚保存的数据?
例如:
只要注册了
DbContext
,事务范围优先,默认情况下是这样
因此,如果您不调用TransactionScope.Complete
(例如,因为与DbContext
相关的异常将您抛出使用块的),所有内容都将按预期回滚。我鼓励您简单地尝试一下(最好是在一旁安装一个探查器来精确地监视正在发生的事情)
简而言之,每个SaveChanges
都会命中数据库,但不会提交。你这么说很有趣。即使未对事务调用“回滚”?@Dee在您离开TS的using
块时,也会隐式调用(这些是C#中using
的语义)。正如您在文档中看到的,如果未调用Complete
,则环境事务将回滚。实际上,上没有“回滚”方法。如果您愿意,EF还支持显式事务而不是TS,有时出于各种原因推荐使用TS。也许这只是一个示例。但是,如果您打算节省一百万行,那么最好考虑一些更有效的解决方案。例如(我维护的)将在一台像样的计算机上以10秒到20秒的时间插入。
using(TransactionScope ts = new TransactionScope( TransactionScopeOption.RequiresNew, new TimeSpan(0, 10, 0)))
{
int counter = 0;
using (MyEntities context = new MyEntities())
{
foreach(var item in context.Items)
{
//process item
if(counter >= 1000)
{
context.SaveChanges(); //if fail here, will already saved changes be rolled back?
counter = 0
}
}
context.SaveChanges();
}
ts.Complete();//what about here?
}