EF Code First DBContext和事务

53

我想知道使用DBContext实现事务的最佳方法。具体而言,

  1. 如果我更改多个实体,DbContext.SaveChanges是否在内部实现了事务?
  2. 如果我想多次调用DbContext.SaveChanges(相同的上下文/不同的上下文),如何实现事务?
2个回答

76
  1. 是的,SaveChanges 内部使用事务。
  2. 使用 TransactionScope 来包装多个对 SaveChanges 的调用。

示例:

using(var scope = new TransactionScope(TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
    // Do something 
    context.SaveChanges();
    // Do something else
    context.SaveChanges();

    scope.Complete();
}

6
请确保使用 Sql 2008 或更新版本作为数据库(或在客户端运行 MSDTC 服务)。早期版本将在第二个 “SaveChanges” 上将事务升级为分布式事务。这是由于 DbContext 内部处理连接的打开和关闭方式所致。 - Lukazoid
能否在第一次保存更改时获取标识?我总是看到 Id = 0。 - JarrettV
@JarrettV - 我认为你的问题是由于隔离级别设置引起的。降低它可能会有所帮助... - Sunny
这在EF 4.3.1中不起作用。在调用context.SaveChanges()之前,我们必须显式地打开ObjectContext上的连接。 - renegadeMind
@renegadeMind:当然,这可以与DbContext一起使用。您所描述的是高级方式,用于避免分布式事务。 - Ladislav Mrnka
@LadislavMrnka 是的,你是正确的;但是我们不是默认情况下要避免DTC吗?我认为我们是这样做的,因此我的回答是这样的! - renegadeMind

0

要进行异步操作,请执行以下操作。

using(var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    // Do something 
    await context.SaveChangesAsync();
    // Do something else
    await context.SaveChangesAsync();

    scope.Complete();
}

参考资料:learn.microsoft.com/zh-cn/ef/ef6/saving/transactions


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接