Core Data Persistent Store Coordinator Lock

I am wondering whether the persistent store coordinator (PSC) locks all connected contexts for writing after calling save() on a context. When the code inside of an (overridden) willSave() method of a (custom) managed object is executed, can there be a second context (connected to the same PSC) where the same code is executed concurrently with respect to the first? As an exemple, let's say I want to access and increment a counter stored in the (global) UserDefaults inside of a willSave() method, would this be automaticvally synced by the PSC (the counter get's modified at no other place in code)?

From the documentation:

"Coordinators do the opposite of providing for concurrency—€”they serialize operations. If you want to use multiple threads for different write operations you use multiple coordinators. Note that if multiple threads work directly with a coordinator, they need to lock and unlock it explicitly."


In other words: No, persistent store coordinator doesn't lock managed object contexts. If they did, you wouldn't need to worry about threading.

That doesn't answer my question. I want to know what happens internally after calling save() on a context. There must be a write lock if several contexts are calling save() concurrently. The question is when this lock happens, before or after the corresponding callback methods of NSManagedObject, e.g. is willSave() guarded by that lock or not.

When you write "There must be a write lock if several contexts are calling save() concurently." it implies to me that you haven't read any of Apple's concurrency or multi-threading documentation. In general, the API aren't thread safe and where the API are thread safe the documentation will make a point of mentioning it. Also, depending on the version of sqlite or the persistent store being used, there may or may not be any write locks at all.


To go back to your original questions:

> When the code inside of an (overridden) willSave() method of a (custom) managed object is executed, can there be a second context (connected to the same PSC) where the same code is executed concurrently with respect to the first? As an exemple, let's say I want to access and increment a counter stored in the (global) UserDefaults inside of a willSave() method, would this be automaticvally synced by the PSC (the counter get's modified at no other place in code)?


If you have two different contexts modifying the same entity at the same time, then those changes are going to proceed concurently and what happens in the end is going to depend on what you've configured for your conflict resolution policies.


Probably more importantly concerning the semantics of things like willSave if you have multiple or nested contexts:

  • If you modify an entity in a leaf context and save, the change gets passed to the parent context. When the parent context is saved, the process repeats if that context has a parent.
  • If there's any locking happening, it's only when the context commits its changes to the persistent store. That's going to be after -willSave.

"That's going to be after -willSave."


That was all I asked for; I didn't ask for a teaching lesson.

Core Data Persistent Store Coordinator Lock
 
 
Q