Redis事务


Redis的事务本质是一组命令的集合,当事务开启期间,所有的命令都按原有的顺序暂时存入一个缓存队列中,并对其命令进行序列化;当事务被执行时,缓存队列中所有的命令按实际情况进行执行。

所以缓存队列具有一次性,顺序性,排他性的特点。

Redis事务不具有隔离性概念

特别注意,因为Redis是一种基于乐观锁来保证数据一致性的机制。在其事务开启期间,所有的命令都被存入缓存队列中,命令并没有被执行,相当于不存在修改这一过程,所以也不存在各事务相互隔离的概念,所有的事务互不影响。

Redis事务不保证原子性

Redis事务执行时,会将缓存队列中的所有命令执行,当其中一条命令因为除命令本身的错误外(即类似set写成sset),其他错误情况下,各命令的执行情况互不影响。

Redis事务的三个阶段

  • 开启事务
  • 命令入队
  • 执行事务

事务执行的多种情况

当事务执行时,可能会因为实际情况而导致各命令的执行情况不同。

事务常用的指令

watch key [key...]	# 监控key值,当事务开启中,key值发生变化,则事务中断
multi				# 开启事务
exec				# 执行事务,(执行事务后,之前的监控全部会清除)
discard				# 取消事务,(缓存队列中的命令被清除)
unwatch 			# 放弃监控,取消watch中对所有的key的监控

事务正常执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name zhangsan
QUEUED
127.0.0.1:6379> set age 18
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> set addr china
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 name "zhangsan"
QUEUED
127.0.0.1:6379> set age 19
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> discard			# 放弃事务
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
127.0.0.1:6379> get name
(nil)

事务遇到命令错误事务异常结束

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name zhangsan
QUEUED
127.0.0.1:6379> set age 12
QUEUED
127.0.0.1:6379> qset addr china		# 命令错误
(error) ERR unknown command `qset`, with args beginning with: `addr`, `china`, 
127.0.0.1:6379> set addr china
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name
(nil)

事务遇到语法错误抛出异常事务继续执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name zhangsan
QUEUED
127.0.0.1:6379> set age 12
QUEUED
127.0.0.1:6379> incr name		# 语法错误
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> get age
"12"

使用watch

在事务开启期间,可能会有其他进程对数据进行修改,而为了保证数据的一致性,避免一些较极端的情况;可以对其数据进行监控,当数据被其他修改时,放弃当前修改。

第一步

# 1号窗口 开始事务,并监听数据
127.0.0.1:6379> set balance 100
OK
127.0.0.1:6379> set cost 0
OK
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby balance 10
QUEUED
127.0.0.1:6379> incrby cost 10
QUEUED


# 2号窗口 修改监听中的数据
127.0.0.1:6379> get balance
"100"
127.0.0.1:6379> decrby balance 15
(integer) 85
127.0.0.1:6379> get balance
"85"

# 1号窗口 执行事务
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get balance
"85"
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值