Redis -- 事务操作

Redis – 事务操作

Redis基本的事务操作

事务:
事务有四个特性(ACID)原子性,一致性,隔离性,持久性
原子性:要么同时成功,要么同时失败。
Redis单条命令是保持原子性的,但是事务不保证原子性!
Redis事务没有隔离级别的概念!
Redis事务的本质:一组命令的集合!一个事务中所有的命令都会被序列化,在事务执行过程中会按照顺序执行(一次性,顺序性,排它性)。
Redis的事务执行顺序:

  • 开启事务(multi)
  • 命令入队(…)
  • 执行事务(exec)
127.0.0.1:6379[3]> MULTI #开启事务
OK
127.0.0.1:6379[3]> set k1 v1
QUEUED
127.0.0.1:6379[3]> set k2 v2
QUEUED
127.0.0.1:6379[3]> get k2
QUEUED
127.0.0.1:6379[3]> set k3 v3
QUEUED
127.0.0.1:6379[3]> exec #执行事务
1) OK
2) OK
3) "v2"
4) OK

#######销毁事务#############
127.0.0.1:6379[3]> MULTI #开启事务
OK
127.0.0.1:6379[3]> set k1 v1
QUEUED
127.0.0.1:6379[3]> set k2 v2
QUEUED
127.0.0.1:6379[3]> set k4 v4
QUEUED
127.0.0.1:6379[3]> DISCARD #取消事务
OK
127.0.0.1:6379[3]> get k4 # 事务队列中的命令都不会被执行
(nil)
127.0.0.1:6379[3]> 
#在java中,编译时异常(代码有错误),事务中所有的代码都不会被执行。redis中,命令有错误,事务中所有的命令都不会执行
127.0.0.1:6379[3]> MULTI
OK
127.0.0.1:6379[3]> set k1 v1
QUEUED
127.0.0.1:6379[3]> set k2 v3
QUEUED
127.0.0.1:6379[3]> set k3 v2
QUEUED
127.0.0.1:6379[3]> getset k3 # 错误命令
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379[3]> set k4 v4
QUEUED
127.0.0.1:6379[3]> exec # 执行命令报错
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379[3]> get k4 # 所有的命令都不会被执行
(nil)
127.0.0.1:6379[3]> 
#如同java中的运行时异常,如1/0,如果redis事务中存在语法性错误,那么在执行命令的时候,没有错误的命令可以正常执行,有错误的命令抛出错误。
127.0.0.1:6379[3]> set k1 "v1"
OK
127.0.0.1:6379[3]> MULTI
OK
127.0.0.1:6379[3]> INCR k1 # 执行的时候失败
QUEUED
127.0.0.1:6379[3]> set k2 v3
QUEUED
127.0.0.1:6379[3]> set k3 v3
QUEUED
127.0.0.1:6379[3]> get k3
QUEUED
127.0.0.1:6379[3]> EXEC # 虽然第一条命令报错了,但是命令依然执行成功了
1) (error) ERR value is not an integer or out of range
2) OK
3) OK
4) "v3"
127.0.0.1:6379[3]> get k2
"v3"
127.0.0.1:6379[3]> get k3
"v3"
127.0.0.1:6379[3]> get k1
"v1"
127.0.0.1:6379[3]> 

悲观锁和乐观锁

悲观锁

  • 很悲观,觉得什么时候都会出问题,无论什么都要加锁。
    乐观锁
  • 很乐观,认为什么时候都不会出问题,所以不会上锁!在更新数据的时候取判断一下在此期间是否有人修改过数据(version)。
  • 获取version
  • 更新的时候比较version
#Redis监视测试
#正常执行
127.0.0.1:6379[3]> set money 100
OK
127.0.0.1:6379[3]> set out 0
OK
127.0.0.1:6379[3]> WATCH money # 监视 money 对象
OK
127.0.0.1:6379[3]> MULTI # 事务正常结束,数据在事务期间没有发生变动,这个时候正常执行成功
OK
127.0.0.1:6379[3]> DECRBY money 20
QUEUED
127.0.0.1:6379[3]> INCRBY out 20
QUEUED
127.0.0.1:6379[3]> EXEC
1) (integer) 80
2) (integer) 20
127.0.0.1:6379[3]> 

#测试多线程修改值,使用watch可以当作redis的乐观锁操作!
127.0.0.1:6379[3]> WATCH money # 监视money
OK
127.0.0.1:6379[3]> MULTI
OK
127.0.0.1:6379[3]> DECRBY money 10
QUEUED
127.0.0.1:6379[3]> INCRBY out 10
QUEUED
127.0.0.1:6379[3]> exec # 执行该命令前,在另一个窗口中执行下一个代码块中的操作,导致事务执行失败
(nil)
127.0.0.1:6379[3]> 

127.0.0.1:6379[3]> set money 1000
OK
127.0.0.1:6379[3]> 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值