代码之家  ›  专栏  ›  技术社区  ›  jonathanpeppers

交易范围-L2E

  •  5
  • jonathanpeppers  · 技术社区  · 15 年前

    在linq to entities上使用system.transactions.transactionscope是否值得?

    MS documentation 它表示,ObjectContext.saveChanges()中的SQL调用都在内部滚动到一个事务中。

    我们有1个数据库连接,即文件系统上的本地sqlite数据库。我们只想确保我们对数据库的所有操作都是原子操作,是否需要TransactionScope? 也就是说,当我们调用某些删除、更新、插入等时,我们希望它们全部发生,或者完全不发生。

    3 回复  |  直到 15 年前
        1
  •  3
  •   Big Endian    15 年前

    乔恩,不,你不需要使用TransactionScope。乐观并发由LINQ自动处理。您提供的链接中的代码示例很好地解释了这一点,您不必自己回滚事务。我将使用与示例中相同的代码:

        try
        {
            // Try to save changes, which may cause a conflict.
            int num = context.SaveChanges();
            Console.WriteLine("No conflicts. " +
                num.ToString() + " updates saved.");
        }
        catch (OptimisticConcurrencyException)
        {
            // Resolve the concurrency conflict by refreshing the 
            // object context before re-saving changes. 
            context.Refresh(RefreshMode.ClientWins, orders);
    
            // Save changes.
            context.SaveChanges();
            Console.WriteLine("OptimisticConcurrencyException "
            + "handled and changes saved");
        }
    

    请注意刷新、重新保存,这将处理您的问题。您可以通过在try块中抛出异常来测试这一点。

    最好的问候

        2
  •  1
  •   Richard    15 年前

    如果你想包括更多的 ObjectContext.SaveChanges 在单个事务中(例如,读取要更改的数据以及更改),则需要利用 TransactionScope .

        3
  •  0
  •   Big Endian    15 年前

    如果您需要执行Richard所说的操作,可以使用以下代码(尽管这似乎不大可能):

    TransactionManager transactionManager = null;
    
    try
    {
        bool isBorrowedTransaction = ConnectionScope.Current.HasTransaction;
        transactionManager = ConnectionScope.ValidateOrCreateTransaction(true);
    
        //MANY SAVES
    
        if (!isBorrowedTransaction && transactionManager != null && transactionManager.IsOpen)
            transactionManager.Commit();
    }
    catch (Exception ex)
    {
        if (transactionManager != null && transactionManager.IsOpen)
            transactionManager.Rollback();
        log.Error("An unexpected Exception occurred", ex);
        throw;
    }