Version conflict on every subsequent conditional put

May 6, 2010 at 4:19 PM
Edited May 6, 2010 at 4:22 PM
Hi, with the way version controls work right now subsequent conditional puts will always fail unless you first do a read to get the latest value for the version controlled attribute. Is there a reason why the version controlled attribute on the object couldn't be updated upon successful put command so that I won't have to do another read before put UNLESS some other process has updated the object in SimpleDB? In which case I would still be able to catch the version conflict and handle it (do a read before retrying) accordingly. So for example, if I'm using a last modified timestamp for version control and my main process will be updating a cached object 99% of time but very rarely some other process can come along and update the data in the database and my main process will need to get the update before committing its own changes (which is where the version control and conditional put come into play). It will remove 90% of the redundant reads I'm doing right now if the library could update the timestamp on the object after it has successfully updated the data in the database. Is this possible with the current version of Simple Savant? Many Thanks,
May 6, 2010 at 4:58 PM
Edited May 14, 2010 at 1:12 AM

Yes, there is a reason why the version controlled property on your object can't be updated by Savant: Because the API also includes other methods that accept PropertyValues collections. Internally Savant works only with PropertyValues collections--every object you pass to Savant is converted to a PropertyValues collection before Savant does anything significant. This allows the 18 methods on SimpleSavant to be distilled down to just 5 methods (the ISimpleSavant2 interface) for all internal operations.

Updating values on the original object would have involved some significant restructuring of this code, so given my time constraints it really was a choice between living with the read before update limitation you're struggling with or not supporting conditional updates for version properties at all.

I'm not sure I understand your point about caching and unnecessary reads, so I'll just explain how conditional updates should work when you have caching turned on:

  1. You read an object from SimpleDb and its values are cached.
  2. You modify the object and save it to SimpleDB and the cached values are updated.
  3. You read the object again to refresh the version on your copy. This read doesn't go to SimpleDb--the new version value is returned from the cache.
  4. If another process updates the version in SimpleDb and you know about the other update, you can simply flush the cached copy using SavantConfig.Cache.Flush() or Remove(string) before you read it back and the version will be read from SimpleDb rather than the cache.
  5. If another process updates the verson in SimpleDb and you don't know about the other update, you'll get the "conditional check failed" exception and can respond appropriately.

Use CacheUtils.CreateKey() to generate the cache key for removal.

UPDATE: Wanted to add one further clarification to the above: You can also get immediate access to the incremented version value (without another get call) by using the Savant typeless and partial-object operations. When you pass a PropertyValues collection to SimpleSavant.PutAttributes(), the original values collection will be updated with the new version value. This is always another option to prevent making unnecessary calls to SimpleDb if for some reason you can't use caching. It's only the Put<T>() method that accepts typed data objects that has the limitation of not copying the new version value back to the original object.