简体   繁体   中英

UnitOfWork with Entity Framework is not committing the transaction

I have an UoW class that has start and commit as below

public class uow
{
    private IDBcontext mydbcontext;
    TransactionScope trans = null;

    public uow(IDBConext mydbcontext)
    {
        this.mydbcontext = mydbcontext;
    }

    public void starttran()
    {
       if (trans == null)
           trans = new TransactionScope(TransactionScopeAsyncFlowOption.enabled);
    }

    public async task Commit()
    {
       var mydb = mydbcontext as IObjectContextAdapter;
       if (mydb != null)
          await mydb.ObjextContext.SaveChangesAsync(SaveOptions.DetectChangesBeforeSave);

       if (trans!=null)
       {
           trans.Complete();
           trans = new TransactionScope();
       }

       mydb.ObjectContext.AcceptAllChanges();
   }
}

Now in my implementation, I insert 2 records into 2 different tables and retrieve the key values back. I then perform another insert into a 3rd table with these 2 keys.

If the 2nd or 3rd insert fails, I need to be able to rollback the first or the first two inserts (the inserts should all be successful or all should fail).

Table1 tab1 = new Table1();
Table2 tab2 = new Table2();
Table3 tab3 = new Table3();

UOW uw = new UOW(mydbcontext);
uw.Starttran();

tab1.createdby = "user1";
tab1.name = "name";

tab1 = mydbcontext.Table1.Add(tab1);
await mydbcontext.SaveChangesAsync();

tab2.createdby = "user1";
tab2.name = "name";

tab2 = mydbcontext.Table2.Add(tab2);
await mydbcontext.SaveChangesAsync();

tab3.table1Id = tab1.Id;
tab3.table2Id = tab2.Id;

tab3 = mydbcontext.Table3.Add(tab3);
await mydbcontext.SaveChangesAsync();

if(tab3.Id > 0)
  await uow.Commit();
else
  await uow.RollBack();

My problem is: the transaction is not committing. As I debug I see, the tab3.Id value is created alright and it is valid. But when I query my SQL Server table, it shows a lock and does not return any query result. When I manually close the debugging session, there is no lock - but the new record does not exist/ is not inserted.

What am I doing wrong here? Read multiple threads on uow here and could not find an answer..

The commit method returns an awaitable Task , so because the call is not awaited, the program may continue to run and even finish before the call is completed. In the last part of your implementation yo should do:

if(tab3.Id > 0)
  await uow.Commit();
else
  await uow.RollBack();  // Assuming that this one is also an async method

A good practice is to add the prefix Async to the methods that support async-await.

Also, but not related to the issue, when you commit your transaction, why are you creating a new transaction scope? It does not seem necessary, and by the unit of work pattern definition, the unit of work should not be re-used once the changes are commited.

if (trans!=null)
{
  trans.Complete();
  trans = new TransactionScope(); // ???
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM