简体   繁体   English

Entity Framework的UnitOfWork没有提交事务

[英]UnitOfWork with Entity Framework is not committing the transaction

I have an UoW class that has start and commit as below 我有一个已经开始并提交的UoW类别,如下所示

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. 现在,在我的实现中,我将2条记录插入2个不同的表中,并取回键值。 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. 正如我调试所看到的,可以tab3.Id创建tab3.Id值,并且它是有效的。 But when I query my SQL Server table, it shows a lock and does not return any query result. 但是当我查询我的SQL Server表时,它显示了一个锁,并且不返回任何查询结果。 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.. 在uow上读取多个线程,找不到答案。

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. commit方法返回一个Waiting Task ,因此由于未等待调用,因此该程序可能会继续运行,甚至在调用完成之前就已完成。 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. 一个好的做法是将前缀Async添加到支持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(); // ???
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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