一、Redis事务和Mysql事务对比
数据库 | MySQL | Redis |
---|---|---|
开启 | start transaction | muitl |
语句 | 普通sql | 普通命令 |
失败 | rollback 回滚 | discard 取消 |
成功 | commit | exec |
二、Redis事务特点
(1)redis的事务实现很简单,只是简单的取消,执行exec命令后,如果multi后面有三条语句,其中有一条是错的,其他两条会执行,不会整体回滚。
(2)使用multi 后执行命令并不是真正执行,而是加入到了执行队列,使用exec命令再统一执行,如果执行discard命令则全部取消。
事务取消
事务提交
注意:
在mutil后面的语句中, 语句出错可能有2种情况
1: 语法就有问题:这种情况,exec时,报错, 所有语句得不到执行。
2: 语法本身没错,但适用对象有问题: 比如 zadd 操作list对象,Exec之后,会执行正确的语句,并跳过有不适当的语句。
三、悲观锁和乐观锁
我正在买票
Ticket -1 , money -100
而票只有1张,如果在我multi之后,和exec之前, 票被别人买了—即ticket变成0了。
我该如何观察这种情景,并不再提交。
1. 悲观的想法:
世界充满危险,肯定有人和我抢,给 ticket上锁,只有我能操作。[悲观锁]
2. 乐观的想法:
没有那么人和我抢,因此,我只需要注意,有没有人更改ticket的值就可以了。 [乐观锁]
读多于写的系统使用多使用乐观锁,写多于读的系统使用悲观锁。
四、Redis的乐观锁
Redis的事务中,启用的是乐观锁,只负责监测key没有被改动。Redis是单线程的,冲突并没有多线程那么普遍。
Redis 使用watch命令监听操作的变量,如果在事务范围内变量被中途修改,则放弃执行事务。
redis 127.0.0.1:6379> watch ticket
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> decr ticket
QUEUED
redis 127.0.0.1:6379> decrby money 100
QUEUED
redis 127.0.0.1:6379> exec
(nil) // 返回nil,说明监视的ticket已经改变了,事务就取消了.
redis 127.0.0.1:6379> get ticket
"0"
redis 127.0.0.1:6379> get money
"200"
watch key1 key2 ... keyN
作用:监听key1 key2..keyN有没有变化,如果有变, 则事务取消
unwatch
作用: 取消所有watch监听