So, I’ve been working on an application that uploads documents to SharePoint and sets metadata on the item via web services. I’ve made a note about how to do this before – although I’ve yet to vent my frustration at not having a web service call to upload a document in a single transaction that either fails or succeeds. Anyway, the result is that I have to upload the file and then set the metadata against it. Unfortunately, this wasn’t working for one of our customers – sometimes it would work, and sometimes it wouldn’t set the metadata.
The intermittent nature of the problem suggests a timing issue – something is under race conditions. Saving the same file to the same library would sometimes work, and sometimes wouldn’t. Naturally, I couldn’t reproduce the problem on my test system.
Looking in the logs from my application, I found that when the metadata wasn’t set, there was an exception being recorded:
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. Error Code: 0x81020015
Interesting. How could my changes conflict with those made by another user? I’ve only just created the item!
Well, there is a way, actually. The customer has an event receiver on all of their Document Libraries, and it runs on the ItemAdded event. Could this be the issue? I decided to write my own ItemEventReceiver class. On the ItemAdded event, I just put in code to make the thread sleep for 3 seconds. I deployed it, and started by doing a normal upload through the SharePoint web UI.
It worked normally, although after I clicked the upload there was a delay of about 3 seconds before I was shown the Edit Item Properties page – which I’d kind of half expected (otherwise, what if the ItemEventReceiver was setting some of those properties?)
Next, I tried using my application to upload a file and set its metadata – and it failed. I got a response back in about a second – that’s for uploading the same file, and setting it’s metadata. Looking in the logs, I could see the same error as is happening on the customer’s system. Clearly, my call to Lists.UpdateListItems was being run at the same time as the ItemEventReceiver – and the event receiver had the item ‘locked’. I deactivated my event receiver – and my test system started to work just fine again.
The reason that the problem is intermittent on the customer’s system is, I think, that sometimes the event receiver has finished before I try to add the metadata – and sometimes it hasn’t. There is a race between the event receiver finishing and setting the metadata starting.
Not sure what to do about it though. I guess I can just keep retrying until it works. It is interesting that the user interface waits for the event receiver to finish whereas the Web services don’t