Tek bir işlemle bahsediyoruz eğer Eh, o (APC nasıl çalıştığını dayalı) atomik olacaktır. Ya bütün yazılı olacak, ya da hiçbiri olacak ...
(Bir nesne başvurulan her yer güncelleme gibi) birden fazla operasyon bahsediyoruz, o zaman bir yarış durumu önlemek için yerleşik bir şey yok. Bunun yerine, ne yapmak gerekir bu verileri güncelleştirmek için çalışırken diğer işlemleri önlemek için kilitleme çeşit uygulamak olduğunu.
Bunu bir yolu operasyonu (veritabanlarında satır düzeyinde kilitleme düşünüyorum) başlamadan önce bilinen bir id öğeyi "önbelleğe alınmış" özel bir kilit yazarak önbelleğe alınan her öğeyi "kilitlemek" için.
Yani, etkilenen önbellek kimlikleri bir dizi varsayarak:
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');
}
}
Peki, o zaman sadece çağırabilirsiniz:
if (getLocks($cacheIds)) {
//Do your operation here
releaseLocks($cacheIds);
}
Şimdi, bu aynı zamanda aynı anahtarla kontrol iki süreçlerin minik ihtimalini önlemek (ve dolayısıyla apc_exists için yanlış dönen, henüz birbirlerinin üzerine yazılmasını ikisi) olmadığını sakının. Bu büyük bir sorun varsa, o zaman double-checked locking kadar okumalısınız