I have the next code in my website (example is very-very simplified for SO, of course):
XDataContext dataContext = new XDataContext();
int currentUserId = GetCurrentUserIdFromSession();
XUser currentUser = dataContext.Users.Single(u => u.Id == currentUserId);
try
{
using (var t = new TransactionScope())
{
int orderId = GetOrderIdFromSession();
XOrder order = dataContext.Orders.Single(o => o.Id == orderId);
order.Status = XOrderStatus.Completed;
order.TransactionId = SomeCalculations(); // exception here
order.CompletedOn = DateTime.UtcNow;
dataContext.SubmitChanges(); // 1
t.Complete();
}
}
catch (Exception ex)
{
XExceptionEvent exceptionEvent = new XExceptionEvent();
exceptionEvent.User = currentUser;
dataContext.ExceptionEvents.InsertOnSubmit(exceptionEvent);
dataContext.SubmitChanges(); // 2
}
When SomeCalculations() throws an exception, order object is in inconsistent state (its Status is XOrderStatus.Completed, but CompletedOn is not set). dataContext.SubmitChanges(); // 1 is not called, everything is good here. BUT. Do you see dataContext.SubmitChanges(); // 2. It is called. And along with XExceptionEvent, it submits unwanted changes of order to my database.
Okay. I tried to create another XDataContext for exceptions. But exceptionsDataContext.SubmitChanges(); says that currentUser is loaded through different XDataContext. Any ideas? Is there any elegant way to cancel non-valid changes of my order?