事务
redis中的事务并不像mysql中那么完美,只是简单的保证了原子性。redis中提供了四个命令来实现事务,MULTI:类似于mysql中的BEGIN;EXEC:类似于COMMIT;DISCARD类似于ROLLBACK;WATCH则是用于来实现mysql中类似锁的功能。具体的使用方法非常简单,例如:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr count
QUEUED
127.0.0.1:6379> incr count
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 2
redis事务的实现原理是把事务中的命令先放入队列中,当client提交了exec命令后,redis会把队列中的每一条命令按序执行一遍。如果在执行exec之前事务中断了,那么所有的命令都不会执行;如果执行了exec命令之后,那么所有的命令都会按序执行。但如果在事务执行期间redis被强制关闭,那么则需要使用redis-check-aof 工具对redis进行修复,删除那些部分执行的命令。下面分几种情况讨论下redis事务中需要注意的地方:
1)入队命令语法错误,此时还没有执行exec命令
虽然redis在碰到exec命令之前不会执行事务中的命令,但是,它会对每个命令进行适当的检查,当发现有某些明显的语法错误时,如参数个数不正确,则会在入队时,返回错误信息,并当看到exec命令调用discard命令进行回滚。例如:
127.0.0.1:6379> get name
"Jeff"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name Kate
QUEUED
127.0.0.1:6379> set name
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name
"Jeff"
2) 当exec执行完毕后,执行其它命令时发生错误
当redis在执行命令时,如果出现了错误,那么redis不会终止其它命令的执行。即只要是正确的命令,无论在错误命令之前还是之后,都会顺利执行。例如:
127.0.0.1:6379> lpush visited "name1"
(integer) 1
127.0.0.1:6379> get name
"Kate"
127.0.0.1:6379&