Redis的事务

Redis 的事务

可以一次性执行多个命令,本质时一组命令的集合,一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入,不许加塞。一个队列中,一次性,顺序的,排他性的执行一系列命令。

如何使用

MULTI 开启事务
EXEC 提交事务
DISCARD 取消事务

正常执行

127.0.0.1:6379> MULTI			# 开启事务
OK
127.0.0.1:6379> set k1 v1		# 添加k1 元素
QUEUED		# 添加到队列中
127.0.0.1:6379> set k2 v2		# 添加k2 元素
QUEUED		# 添加到队列中
127.0.0.1:6379> get k1			# 获取 k1 元素
QUEUED		# 添加到队列中
127.0.0.1:6379> keys *			# 获取所有的元素
QUEUED		# 添加到队列中
127.0.0.1:6379> exec			# 提交事务
1) OK							# 事务提交后,命令返回的结果
2) OK
3) "v1"
4) 1) "k2"
   2) "k1"

放弃事务

127.0.0.1:6379>  MULTI			# 开启事务
OK
127.0.0.1:6379> set k1 v2		# 设置 k1 的值 为 v2
QUEUED
127.0.0.1:6379> DISCARD			# 取消事务
OK
127.0.0.1:6379> get k1  		# 获取 k1 的值 发现还是 v1
"v1"

提一嘴:事务没有提交执行。别的连接也获取不到的

全部出问题

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set k1 v2 
QUEUED
127.0.0.1:6379> set k2 v22
QUEUED
127.0.0.1:6379> setgetee v6				# 这里故意写错
(error) ERR unknown command `setgetee`, with args beginning with: `v6`, 
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> EXEC					# 提交事务
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1					# 获取结果发现所有的语句统统被取消了
"v1"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> get k5
(nil)

谁出错,就找谁,冤有头债有主

127.0.0.1:6379> MULTI			# 事务开启
OK
127.0.0.1:6379> incr k1			# k1 运算  k1 原来的值 v1 
QUEUED
127.0.0.1:6379> set k2 22		
QUEUED
127.0.0.1:6379> set k3 33
QUEUED
127.0.0.1:6379> set k4 44
QUEUED
127.0.0.1:6379> get k4
QUEUED
127.0.0.1:6379> EXEC			# 提交事务
1) (error) ERR value is not an integer or out of range		# 运算时报错 其他执行没有问题
2) OK
3) OK
4) OK
5) "44"
127.0.0.1:6379> get k4 			# 获取 k4 成功
"44"
127.0.0.1:6379> get k1			# 获取k1 还是原来的值
"v1"
watch 监控

悲观锁
顾名思义,就是每次去拿数据的时候都会认为别人会修改,所以每次再拿数据的时候都会上锁,这样别人想拿这个数据就会block知道它拿到锁,传统的关系型数据库里面就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等等,都是在做操作之前先上锁。

乐观锁
顾名思义,就是很乐观,每次去拿数据的时候都会认为别人不会修改,所以不会上锁,但是在更新的时候会判断以下在此期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁适用于多读的应用类型,这样可以提高吞吐量。策略时提交版本必须要大于记录当前版本才能执行更新。

讲个例子:
初始化信用卡可余额和欠额:

127.0.0.1:6379> set balance 100   # 初始化余额100块钱
OK
127.0.0.1:6379> set debt 0		  # 初始化欠额 0 元
OK

开启监控,没有加塞串改,先监控在开启MULTI

127.0.0.1:6379> WATCH balance				# 监控余额
OK
127.0.0.1:6379> MULTI						# 开启事务
OK
127.0.0.1:6379> decrby balance 20			# 余额减少 20 
QUEUED
127.0.0.1:6379> incrby debt 20				# 欠额增加 20 
QUEUED
127.0.0.1:6379> EXEC						# 提交事务
1) (integer) 80 							# 返回
2) (integer) 20

继续开启监控

127.0.0.1:6379> WATCH balance
OK

开启另一个连接

127.0.0.1:6379> get balance			 # 你的女朋友发现你只剩下 80 块钱了
"80"
127.0.0.1:6379> set balance 800		 # 于是给你充到了 800 块钱
OK

这个时候,你继续刷卡吃饭

127.0.0.1:6379> MULTI				 # 开启事务
OK
127.0.0.1:6379> incrby balance 20	 # 余额 减少 20 
QUEUED
127.0.0.1:6379> incrby dept 20		 # 欠额 增加 20
QUEUED
127.0.0.1:6379> EXEC				 # 提交事务 发现 返回 nil
(nil)
127.0.0.1:6379> get balance			 # 获取 余额  发现值为 800 ,没有 减少 20 
"800"

放弃监控

127.0.0.1:6379> WATCH balance 		# 监控 余额
OK
127.0.0.1:6379> set balance 500		# 没有开启事务之前 修改
OK
127.0.0.1:6379> MULTI				# 开启事务
OK
127.0.0.1:6379> set balance 480		# 设置 480	
QUEUED
127.0.0.1:6379> EXEC				# 提交事务 执行失败
(nil)
127.0.0.1:6379> WATCH balance		# 监控余额
OK
127.0.0.1:6379> get balance			# 获取余额
"500"	
127.0.0.1:6379> set balance 480		# 设置为 480
OK
127.0.0.1:6379> UNWATCH				# 放弃监控
OK
127.0.0.1:6379> WATCH balance		# 重新监控余额
OK
127.0.0.1:6379> MULTI				# 开启事务
OK
127.0.0.1:6379> set balance 480		# 设置为480
QUEUED
127.0.0.1:6379> set balance 460		# 设置为460
QUEUED
127.0.0.1:6379> EXEC				# 提交事务,发现执行成功
1) OK
2) OK

一旦执行了EXEC,WATCH 会自动取消

WATCH 指令,类似乐观锁事务提交时,如果key的值已经被别的客户端改变,比如list的值已经被别的客户端 push 了,整个事务队列都不会执行,通过WATCH命令在事务执行之前,监控了多个 key, 倘若在WATCH之后又任何的KEY的值发生了变化,EXEC命令执行的事务,都会被放弃,同时返回 Nullmulti-bulk应答以通知调用者事务执行失败。

使用事务

开启: 以MULTI 开始一个事务
入队: 将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列李米娜
执行: 由EXEC命令出发事务

特性

事务的隔离操作:事务中的所有命令都会序列化、技顺序地执行。事务在执行的过程中,不会被其他客户端发送米的命令请求所打断没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在“事务内的查询要看到事务里的更新,在事务外查询不能看到“这个让人万分头痛的问题不保证原子性。redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回浪

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值