redis事务
事务使用总结:
redis得事务机制允许同时执行多条指令,它是原子性操作,事务中得命令要么全部执行,要么全部不执行;另外事务中的所有指令都会被序列化,而且其执行过程中,不会被即时过来的指令打乱,事务执行期间需要经过三个阶段分别是: 开始事务, 命令入队, 执行事务;
相关命令: multi exec discard watch
multi 开启事务,它总是返回ok结果
exec 该命令负责触发并执行队列中所有的命令;
如果multi开启后因为某些原因没有执行exec命令则事务中所有的命令都不执行;
discard 该命令用来刷新事务中所有排队等待执行的指令,它总是返回ok结果,并且将服务连接状态恢复到正常。
如果已经使用WATCH,那么其会将释放所有被WATCH的key(监控失效)。
watch 标记所有指定的key被监控起来,使其exec命令有条件的执行(乐观锁)
有条件得执行是:事务只能在所有被有被监视键没有被修改的前提下才能执行, 另外exec执行后,所有的watch都会被取消
乐观锁实现:
举个例子,假设我们需要原子性为某个键加1操作(假设INCR不存在),那么应该是这样的执行语句:
SET mykey 1
val = GET mykey
val = val + 1
SET mykey ${val}
单个客户端访问操作没有任何问题,如果是多个客户端同时访问mykey,就会产生资源共享访问问题,比如:现在有个两个客户端访问同一个键mykey,那么mykey的可能是2,但是我们期望的值应该是3才对,这个类似于高并发下的sync锁机制,所以我们需要使用WATCH来监控被共享的键mykey,如下:
WATCH mykey(可监控多个键)
val = GET mykey
val = val + 1
MULTI
SET mykey ${val}
EXEC
NOTE:
虽然大多情况下,多个客户端访问操作同一个键的情况很少或没有,但是不能排除这个特殊情况,所以建议在有可能产生键共享的指令中使用WATCH在EXEC执行前对其监管。
2、Redis不支持回滚(Roll Back)
Redis的事务不支持回滚,这点不同于关系数据库中的事务,所以它的内部保持了简单且快速的特点。另外,Redis不支持回滚是这样考虑的:Redis事务中命令之所以会失败,是由于错误的编程所造成,通过事务回滚是不能回避这个根本问题。
NOTE:
Redis事务中命令执行失败,仍会继续执行后面的执行,在没有特殊干预前提下,直到执行完队列中所有指令为止。