Thursday, July 4, 2013

SPListItem.Update() - The file has been modified by SHAREPOINT\system

SPListItem.Update() - The file has been modified by SHAREPOINT\system

Sometimes it is necessary to have multiple solutions like event handlers, timer jobs, workflows, etc on SharePoint list items, which might work concurrently.

For example I’m working on a SharePoint project in which I create publishing pages using a PowerShell script, based on a XML file like below:


In the PS script I create a publishing page, set the properties as specified in the XML file, and then perform a $item.Update()

$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$page = $pWeb.AddPublishingPage($PageUrl,$Layout)
$item = $page.ListItem             
$item["Title"] = $PageTitle;
$item["Page Content"] = $PageContent;
$item.Update()


I also had an Event Receiver bind to the same pages library, which will update a field in the content type in ItemAdded and ItemUpdated events.

public override void ItemAdded(SPItemEventProperties properties)
{
  using (SPWeb web = properties.OpenWeb())
  {
    try
    {
      Guid pagesLibraryId = Microsoft.SharePoint.Publishing.PublishingWeb.GetPagesListId(web);
      SPList pagesLibrary = web.Lists[pagesLibraryId];
      SPListItem item = properties.ListItem;

      if (item.ContentType.Name.Equals("NewsRelease"))
      {
        item[NEWSCLASSIFICATIONFIELD] = NEWS_RELEASE;
        item.Update();
      }                   
    }
    catch (Exception e)
    {}
  }
}

But when I run the PS script I always get the error: Exception calling "Update" The file has been modified by SHAREPOINT\system.

Reason:
When the page is created in PS, event receiver also fires and updates the list item. Then when PS try to update the lists item SharePoint throws an error since it is trying to perform an operation on a SPListItem that has been modified.

The Solution:
Instead of using SPListItem.Update() method, I used SPListItem.SystemUpdate(false) method in both PowerShell script and in the event receiver.

PowerShell script:     $item.SystemUpdate($false)
Event receiver:        item.SystemUpdate(false);

SPListItem.SystemUpdate() method updates the database with changes made to the list item without changing the Modified or Modified By fields. By passing false as the parameter, SPListItem.SystemUpdate(bool incrementListItemVersion) method will not even increment the item version.

------------ Update -------------

By default SharePoint event receiver ItemAdded executes asynchronously. We can make it synchronous by adding Synchronization tag in the event receiver Elemeny.xml file. This will also fix the issue mentioned in above case.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Receivers ListTemplateId="850">
      <Receiver>       
        <Synchronization>Synchronous</Synchronization>
      </Receiver>     
  </Receivers>
</Elements>

2 comments:

Indrajeet Kumpavat said...

COMException
0x81020015The file FileName.xml has been modified by SHAREPOINT\system on 18 Aug 2014 12:41:01 -0400.

SPException
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

We are facing above two exceptions in following scenarios-
1. While adding/updating the listitem property bag values for document library
2. While adding/updating list item columns for for document library

Please note we have more than one processes are accessing and updating the list items for document library.

Also, Currently We are using SPListItem.SystemUpdate(), to update the list item in document library but if we replace it with SPListItem.SystemUpdate(false), then we are not experiencing exceptions described above. We have understood that passing false parameter in SystemUpdate will not create versions of the list item. However, we want to know that will SystemUpdate with FALSE parameter assure fixing this issue? If not, are there other other alternatives to fix these exceptions?


Another thing, we are not facing the exceptions mentioned above with following SPFile.Update() or SPFolder.Update() as of now. However any one have faced the similar exceptions while updating SPFile and SPFolder?

Chinthana said...

It worked for me. Thanks mate.