何时在 EF 6 中使用 BeginTransaction? vs SaveChanges [重复]

Posted

技术标签:

【中文标题】何时在 EF 6 中使用 BeginTransaction? vs SaveChanges [重复]【英文标题】:When to use BeginTransaction in EF 6? vs SaveChanges [duplicate] 【发布时间】:2015-06-11 13:10:59 【问题描述】:

我对 EF 不太熟悉,但我正在使用 EF 的一些基本功能。最近我收到了https://msdn.microsoft.com/en-us/data/dn456843.aspx 关于 EF6 中的事务。

我之前使用过 SaveChanges(),因为我知道它会将操作包装在事务中。但我注意到我的一些同事正在使用 Database.BeginTransaction()。我四处搜索并得到以下结果,但我无法确认它是正确的。

SaveChanges() 是否仍然可以正常工作并在 SaveChanges 无法满足要求时使用 BeginTransaction,例如在这篇文章http://www.binaryintellect.net/articles/165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx 中将多个 SaveChanges 包装在单个事务中?

在那篇文章中,由于数据库上下文是相同的,我还可以添加两个对象并调用 SaveChanges() 一次,这也可以正常工作吗?我想如果我们要处理多个数据库上下文,那么我们最好使用 BeginTransaction 在一个事务中处理多个 SaveChanges() ?

编辑:

如果我想在一笔交易中有两个加法,以下是不正确的?为什么?

public void CreateAnimals()  
  
    context.Set<Cat>.Add(new Dog());  
    context.Set<Cat>.Add(new Cat());   
    context.SaveChanges();  

编辑 2: 我的主要问题:什么时候可以使用 SaveChanges(),什么时候必须使用 BeginTransaction()? Database.BeginTransaction vs Transactions.TransactionScope 没有提到 SaveChanges

【问题讨论】:

【参考方案1】:

即使您没有明确指定事务,SaveChanges 也始终在事务中执行其 DML。

将实体添加到上下文不会进行数据库调用。执行 DML 的唯一时间是调用 SaveChanges 时。因此,您发布的代码是原子的(您称之为“正确”)。

多个上下文不能共享一个事务(很容易)。在大多数情况下,您不应该使用多个上下文。默认情况下在一个上下文和一个事务中执行您的工作。

【讨论】:

感谢usr,解释的很清楚了。但是我仍然想知道我们什么时候应该使用 BeginTransaction 而不是 SaveChanges,因为 SaveChanges 也可以在一个事务中完成操作 当你想以原子方式执行多个 SaveChanges,或者你想在同一个事务中执行读取操作。【参考方案2】:

您不应该共享上下文。它不是线程安全的。如果您需要可重用的代码,这些代码可能会或可能不会组合成原子操作,请实例化各个上下文(它们非常轻量级)并在代码的更高级别管理原子性。

public void Foo()

    using ( var context = factory.CreateContext() 
    
        context.Set<Cat>.Add(new Cat());
        context.SaveChanges();
    


public void Bar()

    using ( var context = factory.CreateContext() 
    
        context.Set<Cat>.Add(new Dog());
        context.SaveChanges();
    


public void CreateAnimals()

    using ( var context = factory.CreateContext() )
    
        var tran = context.Database.BeginTransaction();
        Foo();
        Bar();
        tran.Commit();
    

【讨论】:

感谢您的代码。但是我还是想知道为什么我不能使用我刚刚添加的代码sn-p。我认为这与线程安全无关。 “外部”上下文上的事务对“内部”上下文没有影响,因为事实上它们之间没有任何关系。

以上是关于何时在 EF 6 中使用 BeginTransaction? vs SaveChanges [重复]的主要内容,如果未能解决你的问题,请参考以下文章

TransactionScope 事务 = new TransactionScope() VS TransactionScope s = context.Connection.BeginTransac

何时不使用实体框架

EF 代码优先数据库/表初始化 - 何时发生?

EF Code First Database Initializer和Migrations Confusion

将 EF 4 EDMX 升级到 EF 6

何时在 DbContext 上执行查询