Simple scenario: OWSTIMER creates a new SPListItem, populates it and calls .Update(). It then fires an HTTP request over to w3wp.exe (front-end app-pool) to invalidate an in-memory cache held there. Intermittently, we note that, though the HTTP request is fired after the .Update() call, the new record is sometimes not found (yet) when w3wp.exe queries the same data.

Key observations:

  • This happens only intermittently, when the WRITE (by OWSTIMER) happens immediately before the READ (by w3wp.exe)
  • The data is always eventually persisted, subsequent refreshes of w3wp.exe (even seconds later) always include the new item
  • Dispose is not called on the parent SPWeb/SPSite before the READ by w3wp.exe

Is it possible that SPListItem.Update() is not entirely synchronous (down to db commit) and that there is a write-delay or transaction isolation at the SPWeb/SPSite levels? Even if the data is committed synchronously, it seems it's not made available to other processes (other SPSite instances) until the request that wrote the data completes or properly disposes.

NOTE: the Update() is happening inside of the EmailReceived(SPList list, Microsoft.SharePoint.Utilities.SPEmailMessage emailMessage, string receiverData) event of an SPEmailEventReceiver, hence why the parent SPWeb/SPSite aren't disposed. If there is indeed transaction isolation at play here, we could change the code to instantiate a new SPSite/SPWeb for the WRITE to guarantee that these opjects are disposed before attempting to flush out the cache in w3wp.exe.

  • Have you disposed all the unmanaged resources, like SPWeb, SPSite, etc. - before your HTTP request? – Andrey Markeev May 12 '11 at 10:38
  • No, they haven't been disposed. Is the transaction isolated until the SPWeb, SPSite are disposed? – Nariman May 12 '11 at 11:09

I think you have to accept that SharePoint, and its API, are designed for good performance in collaboration and content publishing applications. The object model implementation includes all manner of caching mechanisms and optimizations and logic which may change from version to version.

Normally this is not an issue, but in your case you update some content and then immediately initiate a request to another process, which for all we know may be running on a different physical server. I am not surprised that sometimes it takes a few seconds to catch up.

I think you might need a different design approach. Can you use a list item ItemAdded event to do the cache invalidation? I wonder if that would work better.

  • Thanks for your response. We did consider using ItemAdded to invalidate the cache; however, and this is a common misunderstanding, ItemAdded will run in the process that added the item (in this case OWSTIMER) and not in the process where our cache is held (w3wp). – Nariman May 16 '11 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.