I have services been called through the ‘Guardian’ method, that has TransactionScope opened for each request and complete that transaction if everything is fine:
void ExecuteWorker(...)
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
...CallLogicMethods...
scope.Complete();
}
}
One of the methods interacts with ‘External’ service, and in case if that interaction fails all my transaction fails also. As a result, I don’t save required data (been calculated before request to external service.
void DoLogic1(...)
{
CalculateSomeData(...);
SaveCalculatedData(...);
DoRequestToExternalService(...);
}
What is the best way to resolve that issue?
Application is written using C#, .NET 4.0, MS SQL 2008.
Myself I see two solutions
-
Using try/catch:
void DoLogic11(…)
{
CalculateSomeData(…);
SaveCalculatedData(…);try { DoRequestToExternalService(...); } catch(Exception exc) { LogError(...); }}
The lack of this approach is that I’m hiding exception from the caller. But I would like to pass error outside as an exception (to be logged, etc).
- Using ‘Nested transcation’, but I not sure how that works.
Here is my vision it should be:
void DoLogic12(...)
{
using (TransactionScope scopeNested = new TransactionScope(TransactionScopeOption.Suppress))
{
CalculateSomeData(...);
SaveCalculatedData(...);
scopeNested.Complete()
}
DoRequestToExternalService(...);
}
I’ve implemented that, tried to use, but it seems that nested transcation is committed only in case when external is committed also.
Please advise.
I’ve decided to change my ‘ExecuteWorker’ method to create transaction conditionally. Therefore I’m able to create transaction in the ‘DoLogicX’ method itself.