Redis事务

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化,按照顺序执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断

Redis事务的主要作用就是串联多个命令防止别的命令插队,即一个队列中,一次性、顺序性、排他性的执行一系列的命令


multi、exec、discard
从输入multi命令开始,输入的命令都会一次进入命令队列中,但不会执行,直到输入exec后,Redis会将之前的命令队列中的命令依次执行

组队的过程中可以通过discard来放弃组队
可以使用如下的记忆方法
Case1:正常执行
Case2:放弃事务
Case3:全体连坐
一个错误,全体连坐,都不执行
Case4:冤头债主
冤有头债有主,对的执行,错的抛出
Case5:watch监控


事务的错误处理
组队中某个命令出现了错误报告,执行时整个的队列都会被取消
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 1
OK
127.0.0.1:6379> set k4 1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1
QUEUED
127.0.0.1:6379> incr k2
QUEUED
127.0.0.1:6379> incr k3
QUEUED
127.0.0.1:6379> incr k4
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) (error) ERR value is not an integer or out of range
3) (integer) 2
4) (integer) 2



事务冲突的问题
举例:两个请求
一个请求想给金额增加20
一个请求想给金额增加30

悲观锁(Pessimistic Lock)
顾名思义,就是很悲观,每次操作数据时都认为别人会修改,即每次操作数据时都会上锁,这样别人想操作这个数据就会block直到其可以拿到锁。
传统的关系型数据库里就用到了很多这种锁的机制,比如行锁、表锁、读锁、写锁等,就是在做操作之前先上锁
乐观锁(Optimistic Lock)
顾名思义,就是很乐观,每次操作数据时都认为别人不会修改,即每次操作数据都不会上锁,但是在更新的时候回判断一下在此期间别人有没有更新这个数据,可以使用版本号等机制
乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的
watch key [key...]
在执行multi之前,先执行watch key [key...],可以监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,比如某个list已经被别的客户端push/pop过,那么事务将被打断,整个事务队列都不会被执行
操作1 窗口
127.0.0.1:6379> set k1 100
OK
127.0.0.1:6379> watch k1
OK                 (上锁)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr k1
QUEUED       (加入队列操作)

==================================================
在此步启动另外一个操作2 窗口
127.0.0.1:6379> incr k1
(integer) 101
127.0.0.1:6379> get k1
"101"
==================================================

127.0.0.1:6379> exec
(nil)

因为操作2在操作1 对k1加锁之后 修改了k1的值,所以操作1 没有被成功的执行
unwatch
取消watch命令对所有key的监视
如果在执行watch命令之后,exec命令或者discard命令先被执行的话,就不需要再执行unwatch了


Redis事务的三阶段
开启:以MULTI开始一个事务
入队:将多个命令入队到事务中,接受这些命令并不会立即执行,而是等待执行的事务队列里面
执行:由EXEC命令触发事务的执行

Redis事务的三特性
单独的隔离操作
事务中的所有命令都会序列化,按顺序执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
没有隔离级别的概念
队列中的命令没有被提交之前都不会实际的被执行,也就不存在“事务内的查询要看到事务里的更新,事务外的查询不能看到”这个让人万分头疼的问题
不保证原子性
Redis同一个事务中如果有一条命令执行失败,其后的命令任然会被执行,没有回滚
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值