redis事务命令
// 取消事务,放弃执行事务内所有命令
discard
// 执行事务内的所有命令
exec
// 标记事务的开始
multi
// 取消watch命令对所有key的监视
unwatch
// 监视一个或多个key,如果在事务执行之前这个或这些key被其他命令所改动,那么事务将被打断
watch key [key...]
案例1 - 正常执行事务
1.开启事务
multi
2.事务内包含的所有操作,此时redis会将以下的所有操作放到一个队列中去,但不执行,会在提交事务后一并执行
set k1 v1
set k2 v2
get k2
set k3 v3
3.执行事务,执行成功后,会将每一项操作的结果依次输出
exec
案例2 - 当事务在执行exec语句前就出现了error,那么该事务不会被执行
案例3 - 当事务在执行exec语句后才出现error,那么错误操作将不会被执行,正常操作不受影响
1.设置k1值为v1
set k1 v1
2.开启事务,执行以下操作
// 1.事务开启
multi
// 2.k1执行+1操作,但k1是字符,执行+1操作是报异常的,不过在加入事务队列时,并不会出现异常
incr k1
// 3.其他操作
set k2 22
set k3 33
set k4 v4
get k4
- 执行事务
exec
- 可以看到,事务在执行中发生错误时,导致错误的语句不会被执行,但是不会影响到事务中其他正常执行的操作
watch语句学习
现在有这么一个情况,a有100元,b有10元,a向b购买了一个苹果10元,那么a得向b支付10元,a最终剩余90元,b最终有20元,可以用以下事务模拟该过程
set a 100
set b 10
multi
decrby a 10
incrby b 10
exec
watch与乐观锁的机制类似,当watch一个变量时,redis会自动给该变量添加上一个版本号,当执行写入操作时,会先比对版本号,只有版本号一致时,才写入成功。
还是上述案例,但这一次不同点在于,执行事务前,首先watch a,并且在执行事务前,另一个窗口修改了a的值为1000,看看该事务执行结果,过程可以用下面语句进行模拟
set a 100
set b 10
watch a
multi
decrby a 10
incrby b 10
// 注意:必须另起一个窗口将a值修改后,再执行exec语句
exec
此时另起一个窗口,修改a的值为1000后再在原窗口中执行exec语句
set a 1000
结果如下图,可以看到结果为空
流程如下图,A.B表示两个窗口
网友评论