7

I have an SPService class.

MySPService : SPService, IBackupRestore, IDiagnosticManager {

[Persisted]
private string propertyUpdatedByJobsOnAllServers;

 .
 . 
 .   
}

I also have a Job that runs against the SPWebService.ContentService, SPlockType.none.

So this job runs on every machine.

Each job needs to register some values to the MySPService class to the same property.

Like many SPPersistedObject things many servers could be updating properties on them all the time. So how can you ensure that an object with many machines trying to update those properties is "locked" between the time you get/set the proeprty and the .Update on the object.

So can someone tell me how to "Lock" an SPPersistedObject so that many things can safely set properties.

Or point me to an article that says these objects are locked as soon as a reference to them is made (doubtful).

Or an article that says properties are locked when accessed/modified etc.

Or any article that can prove/show me that accessing these objects across multiple machines is safe.

1 Answer 1

2

To detect concurrent edits SPPersitedObjects use an internal version number that is incremented on each successful write.

When you obtain a reference to an SPPersistedObject the version number at that time is remembered in your copy of the object.

When you make a change to your copy and try to .Update() it into the database SharePoint compares the version number you have in your copy with the latest version number in the database.

If they are different you get a concurrent modification exception.

This "optimistic" approach to concurrency improves performance when most uses are read-only and the persisted objects are rarely written to.

To "saefly" update a PersistedObject you can obtain a new copy of the object and retry you will eventually succeed in updating the object. If you keep the time between obtaining the new copy and updating you will reduce the probability of concurrent edits.

Using the above approach as a basis you can implement your own locking scheme by adding a "LockOwner" field to your SPPersistedObject.

When you create your obtain you copy of the SPPersisted Object check if any one else is already the "LockOwner". If the object is locked back off for a "little while" and try again. If the object is not locked set your self as the LockOwner and try to update. If the update succeeds you now have an exclusive lock on the object. If the update fails some one else acquired the lock before you so start again trying to acquire the lock. When you've finished with the lock clear the LockOwner and Update the object again.

If your process is killed before the lock is released you might be left with a stuck lock so you might want to add a lease expiry time to the lock or provide a cmdlet like Remove-SPSolutionDeploymentLock

1
  • With SPPersistedObjectCollection, I've noticed a some voodoo with this one, adding items to the collection seems to self manage the Collection itself. Have you found this the case or it has the same locking strategy and I've been lucky in my tests?
    – BinaryJam
    Commented May 13, 2011 at 8:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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