Well, if you're talking about a single operation, it will be atomic (based upon how APC works). Either it will all be written, or none of it will...
If you're talking about multiple operations (As in updating every place an object is referenced), then there's nothing built in to prevent a race condition. Instead, what you'll need to do is implement some sort of locking to prevent other processes from trying to update that data.
One way you can do this is to "lock" each cached item by writing a special lock "cached" item to a known id before starting the operation (think row level locking in databases).
So, assuming an array of affected cache ids:
function getLocks($cacheIds) {
$locked = array();
foreach ($cacheIds as $cacheId) {
if (apc_exists($cacheId . '_locked')) {
//Another process has this id locked, clear all locks and return
foreach ($locked as $id) apc_delete($id . '_locked');
return false;
} else {
//Use a short TTL to prevent issues if this process dies
apc_store($cacheId . '_locked', 60);
$locked[] = $cacheId;
}
}
return true;
}
function releaseLocks($cacheIds) {
foreach ($cacheIds as $cacheId) {
apc_delete($cacheId . '_locked');
}
}
So, then you can simply call:
if (getLocks($cacheIds)) {
//Do your operation here
releaseLocks($cacheIds);
}
Now, beware that this doesn't prevent the tiny probability of two processes checking for the same key at the same time (and hence both returning false for apc_exists
, yet overwriting each other). If this is a big problem, then you should read up on double-checked locking