I’ve been working with SharePoint 2007 workflows for a couple of months now, and one of the most frustrating issues I’ve encountered is the generation of a “Save Conflict” exception in workflow code.
The scenario we’ve seen is as follows:
- Your workflow code needs to update a field on the list item it is running against.
- You make the change to the field required and called the Update method of the item.
- An exception is thrown with the following message:
Save Conflict – Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.
Now clearly this message seems more aligned with an “interactive” SharePoint user session given it’s advice to “click Back in your Web browser“, but it’s being generated by a programmatic action. Searching the web there are a number of common approaches suggested to address this issue:
- Simply catch the exception, throw it away and try the Update again which should / may succeed.
- Try using the SystemUpdate method which accoring to the MSDN documentation “Updates the database with changes that are made to the list item without effecting changes in the modified time or modified by fields, or optionally, the item version.“
- Simply catch the exception, and throw it away …
We tried all three approaches, and although unpalatable, Option 3 was the one that worked best for us. Options 1 and 2 did not work reliably in our experience. The changes are saved successfully, and we haven’t experienced any issues.
I should say however that a lot of the examples have code pretty much like the following:
try { item.Update(); } catch {}
Now that’s all well and good as long as the only exception that could ever be thrown at this point in time is the “Save Conflict” exception, but obviously that’s not the case, so we’ve adopted the following general approach:
try { item.Update(); } catch (SPException spEx) { if (!spEx.Message.ToLower().Contains("save conflict")) { throw spEx; } }
In this way, should an exception (including a non-SharePoint exception) other than the “Save Conflict” error, we simply re-throw and our surround exception handling takes care of it and logs it.
But the question remains, although simply catching and discarding the exception seems very bad practice, why is the exception being thrown in the first place? Is it a bug? Is it due to mismatched identities under which the workflows are running? I’d love to hear from others on their experiences of this very frustrating circumstance.
July 14th 2008 – For the next installment of my findings regarding this exception, and SharePoint state machine workflows, check out my later post The-delay-activity-is-your-friend.
Hi, just discovered your post, I too have been working with sharepoint workflows, though it seems your a little further up the road than me, I have just setup a sharepoint blog site and was searching for others to links to?
I am just off to OZ for my hols incidentially, so its a “workflow holiday” and i will check out your post again when i’m done.
Thanks man. I just great!. Perhaps is a workaround its enough for what we get the amazing sharepoint spider man!.
Not a problem … Yout might also like to check out my later post on the use of the Delay Activity … It is also extremely relevant to the “save conflict” problem.
Hi , i had the same problem , but i`m not using a work flow i`m simple using a event handler in a list , to change some colunms . And i had the same “Save Conflict” exception, but your code did not solve it .
Does it not aply to event hadlers !?
Hi begot,
Take a look at my second post on this topic … You’ll note that the solution I “proposed” in this post didn’t turn out to be the whole story – OK let’s be blunt – it may have been plain wrong!
In the Workflow context, it turned out that the activities of the first state of my state machine workflow were running *while* the ItemAdded Event was still active (I was firing the workflow on ItemAdded) … which meant that any changes I made to the item on which the workflow was running, *during this first state* conflicted with the pending changes which hadn’t been committed as yet until the ItemAdded event had completed. The solution was forcing the workflow to “dehydrate” by using a workflow delay activity.
With regard to event handlers, this isn’t as relevant. But it could be related. Which event are you trying to handle? If it’s the ItemAdding event, then the same effect might be occurring because, as I understand it, the changes made by the initial addition of the item haven’t been committed. You might solve this problem by doing your updates to the underlying item by handling the ItemAdded event …
Hope that helps.
But what would happen to the data which we are trying to update on the second try which causes error, It would be lost or discarded?
Hi Rahul,
Unfortunately Rahul, it has been some 4 or 5 years since I’ve worked with SharePoint Workflow, and re-reading ALL of the comments on this first post, points out that you really need to read this first post, AND the second one on this topic to get a more comprehensive, and in fact more correct overview of the behaviour.
https://tarambling.com/2008/07/14/sharepoint-workflow-and-the-infamous-save-conflict-error-part-2-the-delay-activity-is-your-friend/
In simple terms, when writing custom workflows for SharePoint, way back then, almost ten years ago, when the first steps of the workflow were executing, the SharePoint item event that had “caused” the workflow to be invoked was still in progress – i.e. the insert or update for example. Therefore if you tried to update say a “status” column for example, or in fact any column on the item, using your workflow, you ended up with this “Save Conflict” error.
And that is why this second part of the blog on this topic, describes using the “Delay” Activity as the very first step of every custom workflow, because it temporarily halts the operation of the workflow, and ensures all operations of the originating event have completed, before the workflow does any work of significance. Of course it means that workflows will very much be run asynchronously, but that is usually an expectation of workflow anyway. My recollection is that under SharePoint 2007 you had some control over that by tuning how frequently the SharePoint Timer service woke up to check if any outstanding workflow tasks were awaiting it.
As I said, the original blog entry identifies the issue, proposes some rather unsatisfactory partial solutions, but doesn’t correctly or fully identify real solutions. My overarching caveat on all of this is that as I said originally, this is SharePoint workflow technology that I have not worked with for 4 or 5 years, AND is technology that is now the best part of 10 years old.
Regards,
Trevor