Hy guys! I'm doing an optimistic locking in Predis. The problem is that the Redis documentation says that when the watched key is modified, then the execute returns a 'Null Multi-bulk reply'. How does it looks like in Predis? Sady I not found any useful docs for Pedis (not counting the very basic tutorials).
Here is how my code looks like at the moment:
private function updateUrlMaxProcessingTime($time, $hoursSinceUnixEpoch) {
//Save the key and the field. They can change anytime because of the timestamp.
$key = $this->statisticsConfig->getKeyFromDataName(StatisticsEnum::URL_MAX_PROCESS_TIME, $hoursSinceUnixEpoch);
$field = $this->statisticsConfig->getFieldFromDataName(StatisticsEnum::URL_MAX_PROCESS_TIME, $hoursSinceUnixEpoch);
//Update the max url processing time if necessary.
$this->redis->watch($key);
$val = $this->redis->hget($key, $field);
if ($val < $time) {
$this->redis->multi();
$this->redis->hset($key, $field, $time);
$result = $this->redis->exec();
//TODO: fix this
if ($result != null && $result[0] != null && $result[0] != -1) {
return true;
} else {
return false;
}
} else {
$this->redis->unwatch();
return true;
}
}
I call the function as long as it's return false.
A null multi-bulk reply returned by Redis is simply translated as NULL
by Predis, so when the client returns that from EXEC
instead of an array it means that the transaction has been aborted by the server. In your script you should just check if $result === null
(note the strict comparison) to safely catch aborted transactions.
Alternatively, instead of directly using MULTI
, EXEC
et al with Predis you can use a more high-level abstraction for transactions exposed by the Predis\Client::multiExec()
method, in a similar way to how it is used in this example with check-and-set and an optional automatic retry count for aborted transactions after which the client throws an exception.