Tag Archives: atomic

PHP atomic update implement with memcache add

Problem
memcache_set is not atomic function
Cache news:
Key = news_134 (134 is news id)
Value = array(‘id’ => 134, ‘title’ => ‘huypv is a web developer’, ‘sapo” => ‘bla bla’, …., ‘view_count’ => 134);
When have guests read news 134 at the same time, the view_count is updated but not correct!

Solution
Create function updateViewCount and make it is atomic
function updateViewCount($id, $inc = 1) {
global $objMemcacheConnId;
$timeout = 15; // TODO change for your scene
$cacheKey = ‘news_’ . $id;
$lockKey = $cacheKey . ‘.lock’;
$getLock = memcache_add($objMemcacheConnId, $lockKey, 1, false, $timeout);
while (!$getLock) {
$getLock = memcache_add($objMemcacheConnId, $lockKey, 1, false, $timeout);
$nbTry++;
usleep(1); // micro second. 1 second = 10^6 micro second (1 milion)
if ($nbTry >= $timeout * 1000000) break;
}
if ($getLock) {
$currentNews = memcache_get($objMemcacheConnId, $cacheKey);
if ($currentNews) {
$newNews = $currentNews;
$newNews[‘view_count’] += $inc;
memcache_set($objMemcacheConnId, $cacheKey, $newNews);
memcache_delete($objMemcacheConnId, $lockKey); # release lock
return true;
} else {
return false; # not found
}
} else {
return false; # timeout
}
}

How to test? Does it work?
Use ab (apache benchmark) or multiple curl to send concurrent request.