Redis事务可以一次执行多个命令, 并且带有以下两个重要的保证:
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
正常执行事务
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set name zhangsan #命令入队
QUEUED
127.0.0.1:6379> set age 15
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> set sex men
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) OK
3) "zhangsan"
4) OK
放弃事务
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379> set k1 laowang #命令入队
QUEUED
127.0.0.1:6379> DISCARD #取消事务
OK
127.0.0.1:6379> get k1
(nil)
编译型异常
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> getset k2 #命令出错
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors. #执行失败
127.0.0.1:6379> get k1 #校验,所有命令都未执行
(nil)
运行时异常
127.0.0.1:6379> set k1 zhangsan #设置k1
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR k1 #入队一条自增命令
QUEUED
127.0.0.1:6379> set k2 lisi
QUEUED
127.0.0.1:6379> set k3 wangwu
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec #执行
1) (error) ERR value is not an integer or out of range #执行时异常 其他命令正常执行
2) OK
3) OK
4) "lisi"
redis监控 watch
1.悲观锁 认为数据会改变 每一步操作都加锁 影响性能
2乐观锁 认为数据不会变化 不会上锁 只有在最后更新数据的时候判断是否有其他操作修改过此数据,
获取version
更新时比较version
实现乐观锁
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
线程1,再次监控、开启事务、入队命令 不执行
127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
线程二 修改money
127.0.0.1:6379> set money 999
OK
线程一 执行事务
127.0.0.1:6379> WATCH money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec #因为线程二对监控的money进行了修改,所以执行事务失败
(nil)
重新开启事务执行,执行成功
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 989