What happens when LINQ updates fail?

advertisements

Here's the scenario:

  • Process 1 (P1) - reads in various flat files one consequence of which is deleting or adding photos URLs to a database table to indicate that these need to be downloaded
  • Process 2 (P2) - Looks up the photo URLs that need to be downloaded, actually performs the download, then marks the record as downloaded

P1 and P2 sometimes run concurrently based on the amount of data to process and sometimes P1 removes records that P2 has already loaded and prepared to download.

This is not actually a problem - if the image is downloaded but no longer needed, the nature of these image URLs is such that it may end up being used at a later date anyway and space is no concern. So, the only trouble is that if P2 selects a group of records and then some of those records cease to exist during the LINQ update, an error is thrown by SubmitChanges() similar to:

"1 of 4 updates failed."

My question is: what happened when this update failed? As far as I can tell, there are 3 possibilities:

  1. The entire transaction was rolled back
  2. The transaction was not rolled back and all records that could be updated were
  3. The transaction was not rolled back and the 1st record was updated but the 2nd failed so the rest of the updates weren't attempted.

The actual call was as follows - no ConflictMode set:

this.SomeDataContext.SubmitChanges();

How would this call be altered so that any updates that could be executed would and the others ignored? Does the following do the trick:

this.SomeDataContext.SubmitChanges(ConflictMode.ContinueOnConflict);

I don't see anything in the MSDN indicating the default ConflictMode of the parameter-less call:

http://msdn.microsoft.com/en-us/library/bb292162.aspx

..though there is an indication in the single parameter call indicating that the default is FailOnFirstConflict:

http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.submitchanges.aspx


With Linq-To-SQL, all changes that are committed when SubmitChanges() is called are saved or rolled back as a single transaction. So, if you have 2 inserts, 2 updates and 2 deletes pending when SubmitChanges() is called, they are all saved or rolled back as a single unit of work.

It is possible to make many SubmitChanges() calls and have all inserts/updates/deletes from all SubmitChanges() treated as a single unit of work by wrapping all the SubmitChanges() calls within a TransactionScope object.