title: Optimistic locking support in NSIncrementalStore subclass
body: <p>I am implementing a custom <em>NSIncrementalStore</em> subclass which uses a relational database for persistent storage. One of the things that I still struggle with is the support for optimistic locking. </p>
  
  <hr>
  
  <p><em><strong>(feel free to skip this lengthy description right to my question below)</em></strong></p>
  
  <p>I analyzed how Core Data's SQLite incremental store approaches this problem by examining SQL logs produced by it and came up with following conclusions:</p>
  
  <ul>
  <li><p>Each entity table in the database has a <strong>Z_OPT</strong> column which indicates the number of times a particular instance of this entity (row) has been modified, starting from 1 (initial insertion).</p></li>
  <li><p>Each time a managed object is modified, <strong>Z_OPT</strong> value in its corresponding database row is incremented.</p></li>
  <li><p>The store maintains cache (referred to as <em>row cache</em> in Core Data docs) of <em>NSIncrementalStoreNode</em> instances, each having a <strong>version</strong> property equal to <strong>Z_OPT</strong> value returned by previous <strong>SELECT</strong> or <strong>UPDATE</strong> SQL query on managed object's row.</p></li>
  <li><p>When a managed object is returned from <em>NSManagedObjectContext</em> (e.g. by executing <em>NSFetchRequest</em> on it), MOC creates snapshot of this object which contains this <strong>version</strong> number.</p></li>
  <li><p>When the object is modified or deleted, Core Data makes sure that it has not been modified or deleted outside the context by comparing versions of cached row and object snapshot. All of this happen when <strong>-save:</strong> is called on the context that the object belongs to. If the versions are different then a merge conflict is detected and handled based on set merging policy.</p></li>
  </ul>
  
  <p>When MOC is being saved, the <strong>-newValuesForObjectWithID:withContext:error:</strong> method is called  for each modified/deleted object which in turn returns <em>NSIncrementalStoreNode</em> with version number. This version is then compared to snapshot's version and if they are different, the save fails with appropriate merge conflicts (at least with default merge policy).</p>
  
  <p>This simple use case works properly with my store since <strong>-newValuesForObjectWithID:withContext:error:</strong> checks the row cache first which is enough if the object was concurrently modified in other context using the same store instance. If this is the case, then the cache contains updated row with higher version number which is enough to detect a conflict.</p>
  
  <p>But how can I detect than the underlying database has been modified outside my store, possibly by other application or other store instance using the same database file? I know this is an unfrequent edge case but Core Data handles it properly and I would prefer to do the same.</p>
  
  <p>Core Data's store uses SQL queries like these to update/delete object's row:</p>
  
  <pre><code>UPDATE ZFOO SET Z_OPT=Y, (...) WHERE (...) AND Z_OPT=X
  DELETE FROM ZFOO WHERE (...) AND Z_OPT=X
  </code></pre>
  
  <p>where:<br>
  <strong>X</strong> - version number last known to the store (from cache)<br>
  <strong>Y</strong> - new version number  </p>
  
  <p>If such a query fails (no rows affected) the row is updated in store's cache and its version compared against the one previously cached.</p>
  
  <hr>
  
  <p><strong>My question is</strong>: how can a custom <em>NSIncrementalStore</em> inform Core Data that optimistic locking failure has occurred for some updated/deleted/locked objects? It is only the store that is able to tell that when it handles <em>NSSaveChangesRequest</em> passed to it its <strong>-executeRequest:withContext:error:</strong> method. </p>
  
  <p>If the underlying database does not change under the store, then conflicts are detected since Core Data calls <strong>-newValuesForObjectWithID:withContext:error:</strong> on each modified/deleted/locked object prior to executing save changes request on the store. I was not able to find any way for <em>NSIncrementalStore</em> to inform Core Data that an optimistic locking failure has occurred <strong>after</strong> it started to handle the save request. Is there some undocumented way to do that? Core Data seems to throw <em>some</em> exception in that case which is then magically translated into failed save request with NSError listing all the conflicts. I am only able to mimic that partly by returning nil from <strong>-executeRequest:withContext:error:</strong> and creating the error message by myself. I think there must be a way to use the standard Core Data conflict handling mechanism in this scenario as well.</p>