Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
Redis的发布和订阅
客户端订阅频道发布的消息
频道发布消息 订阅者就可以收到消息
发布订阅的代码实现
SUBSCRIBE channel1
返回的1是订阅者数量
可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。
单独的隔离的操作
官网说明
https://redis.io/docs/interact/transactions/
MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。
1.MULTI 用来组装一个事务;将命令存放到一个队列里面
2.EXEC 用来执行一个事务;//commit
3.DISCARD 用来取消一个事务;//rollback
4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。
例子:
有关事务,经常会遇到的是两类错误:
“调用 EXEC 之前的错误”,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis 会拒绝执行这一事务
而对于“调用 EXEC 之后的错误”,redis 则采取了完全不同的策略,即 redis 不会理睬这些错误,而是继续向下执行事务中的其他命令。这是因为,对于应用层面的错误,并不是 redis 自身需要考虑和处理的问题,所以一个事务中如果某一条命令执行失败,并不会影响接下来的其他命令的执行例子:。
双十一去购物的时候使用同一张银行卡去付款
10000
一个请求想给金额减8000
一个请求想给金额减5000
一个请求想给金额减1000
解决方案
悲观锁
select * from biao where 1=1 for update;
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,
每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
这样别人想拿这个数据就会block直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制,
比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
12306抢票
乐观锁
version 1
查余额 10000 version:1
10000>8000 -8000 update uuuu set moner-=8000 where version=1 1.1
10000 -5000 UPDATE uuuuu SET MONTY-=5000 WHERE VERSION=1
2000 2000>1000 UPDATE uuuu SET MONTY-=1000 WHERE VERSION=1.1 1.2
version
select * from ttt where uid =1
version money
1 10000
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,
每次去拿数据的时候都认为别人不会修改,所以不会上锁,
但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,
可以使用版本号等机制。乐观锁适用于多读的应用类型,
这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。
“WATCH”可以帮我们实现类似于“乐观锁”的效果,即 CAS(check and set)。
WATCH 本身的作用是“监视 key 是否被改动过”,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。
代码如下:
事物回滚?
redis.clients
jedis
3.2.0
过程略
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.12
org.example
redis-1
1.0-SNAPSHOT
jar
redis-1
http://maven.apache.org
UTF-8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
redis.clients
jedis
3.2.0
junit
junit
3.8.1
test
junit
junit
RELEASE
test
org.junit.jupiter
junit-jupiter
RELEASE
test
注解
@EnableCaching:开启缓存
@Cacheable :标记表示支持缓存
属性:value :缓存的名称 必须指定,也可以是多个
key:缓存的key,可以为空
condition:缓存条件,可以为空,返回结果为true才缓存
@CachePut :一般用在保存,更新方法中,使用和@Cacheable基本一致
@CacheEvict:标注在需要清除缓存元素的方法或类上,和@Cacheable类似。
属性:布尔类型allEntries:表示是否要清除缓存中所有元素,默认为false,为true将忽略指定的key
boforelnvocation:清除操作默认在方法执行后触发,方法如果因为抛出异常而未能成功返回时也不会触发清除操作,可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。