Redis Multi Ensuring Atomicity
Is there a way in redis to make all commands in a 'multi' transaction fail if one command fails.
eg.
<?php
//using phpredis
//connection made
$redis->set('c', 1);
$res = $redis->multi()
->get( 'b' )
->get( 'c' )
->exec();
?>
$res would contain 1, false. Is there a way in redis to make $res return false and have the transaction fail if one of the commands fail?开发者_JAVA百科
From redis docs on transactions:
It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.
According to this article it seems that redis transactions covers ACID semantics only partially and there is no equivalent of rollback although discard commmand can be used to abort the transaction.
What is the real difference between a rollback and a discard ? In SQL Server, for instance, inside a transaction I check for errors at each statement, and then conditionally abort the transaction.
Here you can use the ERR
response of Redis, which phpredis for instance correctly handles, as the error condition.
The following code detects a failed ZADD
, as an example.
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->multi();
$redis->set('ch1',1978); //good command
$f = $redis->zadd('ch2',1231); //this will fail
if (!$f) {
$redis->discard();
echo "Transaction aborted";
}
else {
$redis->exec();
echo "Transaction committed";
}
You can't rollback Redis transactions http://openmymind.net/You-Cant-Rollback-Redis-Transaction/
There is no rollback because it doesn't make that much sense for Redis. The overhead it would bring would be just too unproportional.
The chance of Redis operation failing is just too low. From official doc:
Errors inside a transaction
During a transaction it is possible to encounter two kind of command errors: A command may fail to be queued, so there may be an error before EXEC is called.
For instance the command may be syntactically wrong (wrong number of arguments, wrong command name, ...), or there may be some critical condition like an out of memory condition (if the server is configured to have a memory limit using the maxmemory directive).
A command may fail after EXEC is called, for instance since we performed an operation against a key with the wrong value (like calling a list operation against a string value).
This kind of errors can be prevented and they can be spot while developing.
You can more read about it here: https://redis.io/topics/transactions
精彩评论