How to use transactions with the Entity Framework?

前端 未结 5 479
说谎
说谎 2020-12-13 13:47

When you have code like this:

Something something = new Something();
BlahEntities b = new BlahEntities()    
b.AddToSomethingSet(something);
b.SaveChanges();         


        
相关标签:
5条回答
  • 2020-12-13 14:20
    using System.Transactions;
    
    using (TransactionScope scope = new TransactionScope())
    {
        try
        {
            using(DataContext contextObject = new DataContext(ConnectionString))
            {
                contextObject.Connection.Open();
                // First SaveChange method.
                contextObject.SaveChanges();
    
                // Second SaveChange method.
                contextObject.SaveChanges();
                //--continue to nth save changes
    
                // If all execution successful
                scope.Complete();   
           }
        }
        catch(Exception ex)
        {
            // If any exception is caught, roll back the entire transaction and end the scope.
            scope.Dispose();
        }
        finally
        {
            // Close the opened connection
            if (contextObject.Connection.State == ConnectionState.Open)
            {
                contextObject.Connection.Close();
            }
        }
    }
    

    Find the link below for detailed explanation https://msdn.microsoft.com/en-us/data/dn456843.aspx

    0 讨论(0)
  • 2020-12-13 14:22

    I know that for LINQ to SQL, the data context will create a transaction for SubmitChanges() if there is no existing ambient transaction (TransactionScope is an "ambient" transaction). I haven't seen this documented for LINQ to Entities, but I have seen behavior to suggest that it's true for Entity Framework as well.

    So as long as you use one SubmitChanges() (L2SQL) or SaveChanges() (Linq to Entities) for all the related changes, you should be OK without using TransactionScope. You need a TransactionScope when

    1. Saving multiple changes with multiple SubmitChanges/SaveChanges for one transaction.
    2. Updating multiple data sources within one transaction (e.g., Linq and ASP.NET membership SQL provider).
    3. Calling other methods that may do their own updates.

    I've had trouble with nested TransactionScopes. They're supposed to work, and simple test cases work, but when I get into production code, the "inner" transaction seems to be the same object as the outer transaction. Symptoms include errors that are either "transaction committed, you can't use this transaction any more" or "this transaction object has already been disposed". The errors occur in the outer transaction after the inner transaction has done its work.

    0 讨论(0)
  • 2020-12-13 14:28

    The ObjectContext has a connection property that you can use to manage transactions.

    using (var context = new BlahEntities())
    using (var tx = context.BeginTransaction())
    {
        // do db stuff here...
        tx.Commit();
    }
    

    In the case of an exception the transaction will be rolled back. Because the call to BeginTransaction() requires and open connection it makes sense to wrap the call to BeginTransaction possibly in an extension method.

    public static DbTransaction BeginTransaction(this ObjectContext context)
    {
        if (context.Connection.State != ConnectionState.Open)
        {
            context.Connection.Open();
        }
        return context.Connection.BeginTransaction();
    }
    

    One scenario where I believe this approach could be useful over TransactionScope, is when you have to access two datasources and only need transactional control over one of the connections. I think that in that case the TransactionScope will promote to a distributed transaction which might not be requiered.

    0 讨论(0)
  • 2020-12-13 14:33

    You can place your code within a Transaction scope

    using(TransactionScope scope = new TransactionScope())
    {
        // Your code
        scope.Complete(); //  To commit.
    }
    

    TransactionScope is in the System.Transactions namespace which is located in the assembly of the same name (which you may need to add manually to your project).

    0 讨论(0)
  • 2020-12-13 14:37

    In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes. When you execute another such operation a new transaction is started. For Newest Entity Framework version: 6.0 +

    Read More Here: EntityFramework and Transaction

    0 讨论(0)
提交回复
热议问题