In my application I have method looks like this:
public static bool DoLargeOperation()
{
bool res = true;
res = res && DoFirstSubOperation();
res = res && DoSecondSubOperation();
res = res && DoThirdSubOperation();
return res;
}
And each of the internal methods looks like this:
public static bool DoFirstSubOperation()
{
using (var context = new EntityFrameworkContext())
{
// data modification.
context.SaveChanges();
}
}
For example, DoFirstSubOperation()
and DoSecondSubOperation()
complete successfully, but DoThirdSubOperation()
fails.
How do I rollback the changes made by the first two functions?
This approach has not brought results:
using (var transaction = new TransactionScope())
{
res = res && DoFirstSubOperation();
res = res && DoSecondSubOperation();
res = res && DoThirdSubOperation();
}
The only solution I see is to define the context like so:
public static bool DoLargeOperation()
{
bool res = true;
using (var context = new EntityFrameworkContext())
{
using (var transaction = context.Database.BeginTransaction())
{
res = res && DoFirstSubOperation(context);
res = res && DoSecondSubOperation(context);
res = res && DoThirdSubOperation(context);
if (res)
{
transaction.Commit();
}
else
{
transaction.Rollback();
}
}
}
return res;
}
But is it acceptable to do so? Or is there another solution?
Yes, that is the correct pattern. Passing the context into the methods allows the methods to be reused in multiple locations because the context and transaction will be managed by the caller.
Although, you will probably want to stop processing subsequent methods once the first one fails. You also probably want to wrap the call to the children in a try/catch so that any exception allows the rollback to occur correctly...
try
{
res = DoFirstSubOperation(context);
if (res)
res = DoSecondSubOperation(context);
if (res)
res = DoThirdSubOperation(context);
if (res)
transaction.Commit();
else
transaction.Rollback();
}
catch
{
transaction.Rollback();
}
If your child methods already handle exceptions then you can forgo the try/catch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With