一、事务概述
Redis事务是一组命令的集合。事务同命令一样是Redis的最小执行单位,要么执行,要么不执行。
事务的原理是先将属于一个事务的命令发送给Redis,然后在让Redis依次执行这些命令。
Redis在事务中没有立即执行sadd操作,而是返回QUEUED表示这两条命令已经进入等待执行的事务队列中了。
使用EXEC命令告诉Redis将等待执行的事务队列中的所有命令按照发送顺序依次执行。
EXEC返回值就是这些命令的返回值组成的列表,返回值顺序和命令的顺序相同。
Redis保证一个事务中的所有命令要么都执行,要么都不执行。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了EXEC命令,所有的命令就都会执行,即使此后客户端断线也没有关系,因为Redis中已经记录了所有要执行的命令。
Redis的事务还能保证一个事务内的命令依次执行而不被其他命令插入。
二、错误处理
事务中的某个命令执行出错,怎么办?
(1)语法错误,指命令不存在或者命令参数的个数不对。命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足
(如果服务器使用 maxmemory 设置了最大内存限制的话)
3个命令,一个正确,两个错误,而只要有一个命令有语法错误,执行EXEC命令后Redis就会直接返回错误,连语法正确的命令也不会执行。
在 Redis 2.6.5 以前,Redis 只执行事务中那些入队成功的命令,而忽略那些入队失败的命令
(2)运行错误,指命令执行时出现的错误,比如使用散列类型的命令操作集合类型的键。在执行以前Redis无法发现,所以在事务中这样的命令会被接受并执行,
一条命令出现了运行错误,事务里其他的命令依然会继续执行。
虽然sadd key 2出现了错误,但是set key 3依然执行了。
取消一个事务:
Redis 在事务失败时不进行回滚,而是继续执行余下的命令
1.Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,
三、watch命令
事务中每个命令的执行结果都是最后一期返回的,无法将前一条命令的结果作为下一条命令的参数。
比如说get值,+1,再set
为了解决这个问题,在get获得键值后保证该键值不被其他客户端修改,直到函数执行完成后才允许其他客户端修改该键值。可以防止竞态条件。
执行watch命令后,事务执行前修改了key的值,set key 2,所以最后事务中的命令set key 3没有执行,EXEC命令返回空结果。
由于watch命令的作用只是当被监控的键值被修改后阻止之后一个事务的执行,而不能保证其他客户端不修改这一键值,所以我们需要在EXEC执行失败后重新执行整个函数。
执行EXEC后会取消所有键的监控,也可以用unwatch命令来取消监控。
四、生存时间
使用expire命令设置一个键的生存时间,到时候后redis会自动删除它。
如果想让session:29e3d键在15分钟后被删除
返回1表示成功,0表示键不存在或者设置失败。
一个键还有多久时间被删除,可以用ttl命令,返回值是键的剩余时间(单位s)
当键不存在时ttl返回-1.同样会返回-1是没有为键设置生存时间(永久存在)。
想取消生存时间设置,即恢复永久,用persist命令。成功1,失败0
除次之外,还可以set或getset命令为键赋值也会同时清除键的生存时间。
使用expire会重新设置键的生存时间。
其他只对键值进行操作的命令(incr、lpush、hset、zrem)都不会影响键的生存时间。
expire命令时间参数必须是整数,s。更精确,使用pexpire,单位是毫秒。对应可以用pttl返回剩余时间。
如果watch命令监测了一个拥有生存时间的键,该键时间到期后自动删除并不会被watch命令认为该键被改变。
另外两个命令
expireat和pexpireat,与前面差别使用unix时间作为时间参数。expireat单位是秒,pexpireat单位是毫秒。
引用
http://my.oschina.net/OutOfMemory/blog/300173