Redis事务

什么是事务?

Redis的事务和mysql事务在概念上是类似的,不都是把一些操作绑定成一组,让这组可以批量执行。

但是redis事务跟mysql事务还是有区别的:

  • 弱化的原子性:redis没有像mysql一样的回滚机制,只能做到把一些操作打包到一起,要么都执行要么都不执行,但不确保正确,只要有一个失败就会恢复到初始状态。
  • 不保证一致性:不涉及“约束”,没有“回滚”,mysql的一致性体现在运行事务前和运行后,结果都是合理有效的,中间不会出现非法状态。
  • 不需要隔离性:redis没有隔离级别,redis是单线程模型的服务器程序,所有的请求/事务都是串行执行。
  • 不需要持久性:redis本身就是内存数据库,数据存储在内存中,虽然redis也有持久化机制,但这跟事务没有直接关系。

redis事务本质上是在服务器搞了一个事务队列。每次客户端在事务中的一个操作都会把命令先发给服务器,放到事务队列里,但不会立即执行。

收到EXEC命令之后才会执行事务队列中的操作(redis事务的意义就是为了“打包”,避免其他客户端的命令插队到中间)。

 Redis事务为什么不能跟mysql一样强大?

MySQL事务强大是付出了一定代价的,空间上,要花费更多的空间存储更多的数据,时间上,月要有更大的执行开销。

所以,正是因为上面的问题,才有了redis上场的机会。

Redis事务的使用场景

redis事务可以用于“秒杀”场景中~

比如一个游戏机只发放1000台,但却有1001个购买成功,就会出现问题。

 假如商品剩余一个,两个代码块都执行,那么结果就是商品个数会变成-1,这样会出现“线程安全”问题;在多线程中可以用加锁的方式避免插队,但在redis中直接使用事务即可:

将两个代码块放入事务队列中,并不会一起执行,而是开启事务之后先执行一个代码块,执行完毕后另一个代码块商品个数就是0,无法执行了,就不会出现线程安全问题。 

 事务操作

MULTI

开始一个事务,执行成功返回ok

EXEC

真正执行事务,如下图:

 可以看到每添加一个操作,都会出现QUEUED,说明命令已经进入客户端队列了,真正执行EXEC的时候,才会把上述操作发送给服务器,才能回去到k的值。

DISCARD

放弃当前事务,会直接清空事务队列,之前的操作都不会执行到。

WATCH

在执行事务的时候,如果某个事务中修改的值被其他客户端修改了,此时就会出现数据不一致的问题 ,结果还是原来事务中修改的值。

这种时候,就容易产生歧义,要告诉用户当前操作存在风险。

watch命令就是解决这个问题的,watch可以在客户端上监控一组具体的key:

  • 当开启事务的时候,如果对watch监控的key进行修改,就会记录当前key的“版本号”(版本号是个简单的证书,每次修改都会导致版本号增大,服务器来维护每个key的版本号情况)
  • 在真正提交事务的时候,如果发现当前服务器上key的版本号跟事务开始时的版本号不同,就会让事务执行失败。

UNWATCH

取消对key的监控,相当于watch的反向操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值