redis中的事务与锁

举报
小小张自由--张有博 发表于 2022/05/21 15:14:47 2022/05/21
【摘要】 redis中的事务与锁

Redis事务的定义

Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。

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

Redis事务的主要作用就是串联多个命令防止别的命令插都队。

总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令


事务的三大特性

单独的隔离操作

事务中的所有命令都会序列化、按照顺序的执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

没有隔离级别的概念

队列中的命令没有提交之前都不会实际被执行。因为事务提交之前任何指令都不会被实际执行

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

不保证原子性:

原子性:要么全部执行,要么回滚,不可中断

事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。


Redis事务的三个阶段:

(1)开始事务

(2)命令入队

(3)执行事务/放弃事务

跟MySQL的事务不一样,很大差别。



Multi、Exec、Discard、WATCH


从输入Mt命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

组队的过程中可以通过discard来放弃组队。

## 保存
127.0.0.1:6379[1]> multi    
OK
127.0.0.1:6379[1]> set key1 value1
QUEUED
127.0.0.1:6379[1]> set key2 value2
QUEUED
127.0.0.1:6379[1]> set key3 value3
QUEUED
127.0.0.1:6379[1]> exec
1) OK
2) OK
3) OK


## 未保存
127.0.0.1:6379[1]> multi
OK
127.0.0.1:6379[1]> set a1 v1
QUEUED
127.0.0.1:6379[1]> set a2 v2
QUEUED
127.0.0.1:6379[1]> DISCARD
OK

事务的错误处理

发生异常的情况

1.在组队阶段发生异常,导致异常

组队中某个命令出现了错误,执行时整个的所有队列都会被取消。

2.在执行阶段发生异常,导致异常

如果执行阶段某个命令出现了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。


事务冲突问题

双十一某个账户一共有10000,此时并发产生了三个请求。

一个请求想给金额减8000

一个请求想给金额减5000

一个请求想给金额减1000

悲观锁

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

(令牌桶)谁先抢到,那谁就有权限操作资源。

乐观锁

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

抢票,抢订单的过程(抢资源:每个人都有权利去操作资源)。



Redis加锁

监听:WATCH key

在执行multi之前,先执行watch key1【key2】,可以监视一个(或多个)key,如果在事务执行之前这个(或这些)ky被其他命令所改动,那么事务将被打断。


取消监听: UNWATCH

取消WATCH命令对所有key的监听

一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。故当事务执行失败后,需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作。


watch 命令则是用于客户端并发情况下,为事务提供一个乐观锁(CAS,Check And Set),也就是可以用 watch 命令来监控一个或多个变量,如果在事务的过程中,某个监控项被修改了,那么整个事务就会终止执行。

WATCH:表示监视指定的 key,「 该命令只能在 MULTI 命令之前执行 」,如果监视的 key 被其它客户端修改,那么 EXEC 将会放弃执行队列中的所有命令。

下面就来演示一下,首先 watch 是需要搭配 multi 事务来使用的。一般是先 watch key,然后开启事务对 key 操作。



个人疑问

redis事务存在的问题,只能规定本事务的命令,无法管理其他命令


使用监听解决redis事务的问题。

总结

(1) 事务提供了一种将多个命令打包,然后一次性、有序地执行的机制。

(2) 多个命令会被人队到事务队列中, 然后按先进先出(FIFO)的顺序执行。

(3) 事务在执行过程中不会被中断,当事务队列中的所有命令都被执行完毕之后,事务才会结束。

(4) 带有WATCH命令的事务会将客户端和被监视的键在数据库的watched_keys字典关联,当键被修改时,程序会将所有监视被修改键的客户端的REDIS_DIRTY_CAS标识打开,服务只有在REDIS_DIRTY_CAS标识没有打开时,才会执行客户端提交的事务,否则服务器拒绝执行事务。

(5) Redis事务不支持回滚机制。



参考资料

https://blog.csdn.net/weixin_43520450/article/details/107548277

https://blog.csdn.net/qq_31960623/article/details/118333404

https://www.cnblogs.com/traditional/p/13298599.html

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。