UnitOfWork with Entity Framework不提交事务

时间:2016-01-01 19:43:38

标签: c# sql-server async-await entity-framework-6 unit-of-work

我有一个utf8类,其启动和提交如下

UoW

现在在我的实现中,我将2条记录插入到2个不同的表中并检索键值。然后我用这两个键执行另一个插入第三个表。

如果第二次或第三次插入失败,我需要能够回滚第一次或前两次插入(插入应该全部成功或全部失败)。

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();
   }
}

我的问题是:交易没有提交。正如我调试所看到的那样,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(); 值创建正常并且有效。但是,当我查询我的SQL Server表时,它显示一个锁,并且不返回任何查询结果。当我手动关闭调试会话时,没有锁定 - 但新记录不存在/未插入。

我在这里做错了什么?在这里阅读多个线程并找不到答案..

1 个答案:

答案 0 :(得分:2)

commit方法返回一个等待的Task,因为没有等待呼叫,程序可能会继续运行,甚至在呼叫完成之前完成。在你的实现的最后部分你应该做:

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

一个好的做法是将前缀Async添加到支持async-await的方法中。

此外,但与问题无关,当您提交事务时,为什么要创建新的事务范围?这似乎没有必要,并且通过工作单元模式定义,一旦提交更改,就不应重新使用工作单元。

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