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.