127.0.0.1:6379> MULTI # 开始执行事务 OK # 命令入队 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> get k2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> exec# 执行事务 1) OK 2) OK 3) "v2" 4) OK 127.0.0.1:6379>
放弃事务
1 2 3 4 5 6 7 8 9 10 11 12 13
127.0.0.1:6379> MULTI # 开始事务 OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k4 v4 # 设置k4的值 QUEUED 127.0.0.1:6379> DISCARD # 取消事务 OK 127.0.0.1:6379> get k4 # 取k4,不能取到 (nil) 127.0.0.1:6379>
编译型异常(代码有问题,命令有错),事务中所有的方法都不会执行!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
127.0.0.1:6379> MULTI # 开启事务 OK 127.0.0.1:6379> set k4 v4 # 设置k4-v4 QUEUED 127.0.0.1:6379> xxxx # 写一个错误语句,这会导致我们的整个事务全部不会被执行 (error) ERR unknown command `xxxx`, with args beginning with: 127.0.0.1:6379> set k5 v5 QUEUED 127.0.0.1:6379> EXEC # 执行事务 (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k4 # 可以看到拿不到k4和k5的值 (nil) 127.0.0.1:6379> get k5 (nil) 127.0.0.1:6379>
127.0.0.1:6379> set k1 'v1' OK 127.0.0.1:6379> MULTI # 开启事务 OK 127.0.0.1:6379> incr k1 # k1的value自增加,但是它的value不是integer类型,会报异常,但是不影响事务中其他语句的执行 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> exec# 执行事务 1) (error) ERR value is not an integer or out of range 2) OK 3) OK 127.0.0.1:6379> get k2 # 能获取到k3和k4的值 "v2" 127.0.0.1:6379> get k3 "v3" 127.0.0.1:6379>
127.0.0.1:6379> set money 100 OK 127.0.0.1:6379> set out 0 OK 127.0.0.1:6379> watch money # 监视money对象 OK 127.0.0.1:6379> multi # 事务正常结束,数据期间没有发生变动,这个时候就执行成功 OK 127.0.0.1:6379> DECRBY money 20 QUEUED 127.0.0.1:6379> incrby out 20 QUEUED 127.0.0.1:6379> exec 1) (integer) 80 2) (integer) 20 127.0.0.1:6379>
测试多线程修改值,使用watch可以当做redis的乐观锁操作!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
127.0.0.1:6379> watch money # 监视money OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> DECRBY money 20 QUEUED 127.0.0.1:6379> incrby out 20 QUEUED 127.0.0.1:6379> exec# 执行之前,另外再开一个redis连接,修改让money减10,导致这个事务执行失败 (nil) 127.0.0.1:6379> get money "70" 127.0.0.1:6379> get out "20" 127.0.0.1:6379>
如果事务执行失败,就先解锁,获取新的money,再次监视,再次执行事务
1 2 3 4 5 6 7 8 9 10 11 12 13 14
127.0.0.1:6379> UNWATCH # 先解锁 OK 127.0.0.1:6379> watch money # 获取新的值,再次监视 OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> DECRBY money 20 QUEUED 127.0.0.1:6379> incrby out 20 QUEUED 127.0.0.1:6379> exec# 会再次对比监视的值是否发生了变化,如果没有变化则执行成功,否则执行失败 1) (integer) 50 2) (integer) 40 127.0.0.1:6379>