문제

내 앱에서 캐싱 로직을 통합 할 생각입니다.

주로 객체와 객체 목록을 APC에 캐시합니다. 객체가 업데이트/제거되면 자동으로 무효화 할 수있는 방법을 구현합니다.

그러나 원자력은 어떻습니까? 작업이 원자인지 확인하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

글쎄, 단일 작업에 대해 이야기하고 있다면 APC의 작동 방식을 기반으로 원자력이됩니다. 그것은 모두 쓰여지거나 아무도 ...

여러 작업에 대해 이야기하고 있다면 (모든 장소를 업데이트 할 때와 같이 객체를 참조 할 때) 레이스 조건을 방지하기위한 내장은 없습니다. 대신, 당신이해야 할 일은 다른 프로세스가 해당 데이터를 업데이트하려고하지 않도록 일종의 잠금을 구현하는 것입니다.

이 작업을 수행 할 수있는 한 가지 방법은 작업을 시작하기 전에 (데이터베이스에서 행 레벨 잠금을 생각해보십시오)로 알려진 ID에 특수 잠금 "캐시 된"항목을 작성하여 각 캐시 된 항목을 "잠금"하는 것입니다.

따라서 영향을받는 캐시 ID 배열을 가정합니다.

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');
    }
}

그러면 간단히 전화 할 수 있습니다.

if (getLocks($cacheIds)) {
    //Do your operation here
    releaseLocks($cacheIds);
}

이제 두 프로세스가 동시에 동일한 키를 점검하는 작은 확률을 방해하지는 않음을 조심하십시오 (따라서 둘 다 False를 반환합니다. apc_exists, 그러나 서로를 덮어 쓰고 있습니다). 이것이 큰 문제라면, 당신은 이중 확인 잠금

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top