Redis 中的事务
Mysql与redis的区别
Mysql Redis
开启 start transaction muitl
语句 普通sql 普通命令
失败 rollback 回滚 discard 取消
成功 commit exec
127.0.0.1:6379> set num1 200
OK
127.0.0.1:6379> set num2 400
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby num2 100
--将语句保存在队列queued中,不执行,只有exec才从队列中拿出来执行
QUEUED
127.0.0.1:6379> incrby num1 100
QUEUED
127.0.0.1:6379> exec
1) (integer) 300
2) (integer) 300
注意:
1 rollback与discard 的区别
如果已经成功执行了1条语句, 第2条语句出错.
Rollback后,前1条的语句影响消失,
Discard只是结束本次事务,前1条语句造成的影响仍然还在
127.0.0.1:6379> set num1 200
OK
127.0.0.1:6379> set num2 400
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby num1 100
QUEUED
127.0.0.1:6379> decrby num2 aa
QUEUED
127.0.0.1:6379> exec
1) (integer) 300
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get num1
"300"
127.0.0.1:6379> get num2
"400"
127.0.0.1:6379>
2 在mutil后面的语句中, 语句出错可能有2种情况
1: 语法就有问题,
执行exec时,报错, 所有语句得不到执行
127.0.0.1:6379> set num1 200
OK
127.0.0.1:6379> set num2 400
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby num1 100
QUEUED
127.0.0.1:6379> asdad
(error) ERR unknown command 'asdad'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get num1
"200"
127.0.0.1:6379> get num2
"400"
2: 语法本身没错,但适用对象有问题. 比如set num2 40;decrby num2 aa
Exec之后,会执行正确的语句,并跳过有不适当的语句.
127.0.0.1:6379> set num1 200
OK
127.0.0.1:6379> set num2 400
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby num1 100
QUEUED
127.0.0.1:6379> decrby num2 aa
QUEUED
127.0.0.1:6379> exec
1) (integer) 300
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get num1
"300"
127.0.0.1:6379> get num2
"400"
127.0.0.1:6379>
锁
Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.有改动,执行的事务就不成功。
语法
watch key1 key2 …
案列买票
--当前票数为1
127.0.0.1:6379> set ticket 1
OK
--用户A的钱500
127.0.0.1:6379> set money 500
OK
--设置锁,如果票数发生变化,下面的事务不执行
127.0.0.1:6379> watch ticket
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decr ticket
QUEUED
127.0.0.1:6379> decrby money 100
QUEUED
--在exec之前,另一个用户B购买了票数,之后当前用户A执行exec
127.0.0.1:6379> exec
(nil)--表示用户A的事务没有生效
另一个用户B,在用户A exec之前,先买了票
127.0.0.1:6379> decr ticket
(integer) 0
127.0.0.1:6379>