如何在线实现手机版网站建设,js网站开发视频,wordpress怎么改变布局,wordpress 判断是否有文章一、订阅和发布
Redis 发布订阅 (pub/sub) 是一种消息通信模式#xff1a;发送者 (pub) 发送消息#xff0c;订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
Redis的发布和订阅
客户端订阅频道发布的消息 频道发布消息 订阅者就可以收到消息 发布订阅的代…
一、订阅和发布
Redis 发布订阅 (pub/sub) 是一种消息通信模式发送者 (pub) 发送消息订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
Redis的发布和订阅
客户端订阅频道发布的消息 频道发布消息 订阅者就可以收到消息 发布订阅的代码实现
1、 打开一个客户端订阅channel1
SUBSCRIBE channel1 2、打开另一个客户端给channel1发布消息hello
publish channel1 hello 返回的1是订阅者数量
3、打开第一个客户端可以看到发送的消息 二、事务
1.事务简介
可以一次执行多个命令本质是一组命令的集合。一个事务中的 所有命令都会序列化按顺序地串行化执行而不会被其它命令插入不许加塞。
单独的隔离的操作
官网说明
https://redis.io/docs/interact/transactions/
MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。 1.MULTI 用来组装一个事务将命令存放到一个队列里面
2.EXEC 用来执行一个事务//commit
3.DISCARD 用来取消一个事务//rollback
4.WATCH 用来监视一些 key一旦这些 key 在事务执行之前被改变则取消事务的执行。
例子 有关事务经常会遇到的是两类错误
1.调用 EXEC 之前的错误
“调用 EXEC 之前的错误”有可能是由于语法有误导致的也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况redis 都会进行记录在客户端调用 EXEC 时redis 会拒绝执行这一事务 2.调用 EXEC 之后的错误 2.redis事务冲突
双十一去购物的时候使用同一张银行卡去付款
10000
一个请求想给金额减8000
一个请求想给金额减5000
一个请求想给金额减1000 解决方案
悲观锁
select * from biao where 11 for update 悲观锁(Pessimistic Lock), 顾名思义就是很悲观
每次去拿数据的时候都认为别人会修改所以每次在拿数据的时候都会上锁
这样别人想拿这个数据就会block直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制
比如行锁表锁等读锁写锁等都是在做操作之前先上锁。
12306抢票
乐观锁
version 1
查余额 10000 version1
100008000 -8000 update uuuu set moner-8000 where version1 1.1
10000 -5000 UPDATE uuuuu SET MONTY-5000 WHERE VERSION1
2000 20001000 UPDATE uuuu SET MONTY-1000 WHERE VERSION1.1 1.2 version
select * from ttt where uid 1
version money
1 10000
乐观锁(Optimistic Lock), 顾名思义就是很乐观
每次去拿数据的时候都认为别人不会修改所以不会上锁
但是在更新的时候会判断一下在此期间别人有没有去更新这个数据
可以使用版本号等机制。乐观锁适用于多读的应用类型
这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。
3.WATCH
“WATCH”可以帮我们实现类似于“乐观锁”的效果即 CAScheck and set。
执行顺序multibegin - execcommit - discardrollback
WATCH 本身的作用是“监视 key 是否被改动过”而且支持同时监视多个 key只要还没真正触发事务WATCH 都会尽职尽责的监视一旦发现某个 key 被修改了在执行 EXEC 时就会返回 nil表示事务无法触发。
代码如下: 事务回滚 三、Java连接redis
1. 创建java项目
略
2. 添加redis的依赖
dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.2.0/version
/dependency
3. 连接redis 四、redis整合springboot项目
1. 创建项目
略
2. 添加依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactIdversion2.6.0/version/dependencydependencygroupIdredis.clients/groupIdartifactIdjedis/artifactId/dependency 3. 编写配置文件 4. 设置配置类
package org.example.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;import java.time.Duration;EnableCaching
Configuration
public class RedisConfig extends CachingConfigurerSupport {/*** 连接池的设置** return*/Beanpublic JedisPoolConfig getJedisPoolConfig() {JedisPoolConfig jedisPoolConfig new JedisPoolConfig();return jedisPoolConfig;}/*** RedisTemplate* param factory* return*/Beanpublic RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) {RedisTemplateString, Object template new RedisTemplate();RedisSerializerString redisSerializer new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om new ObjectMapper();// 指定要序列化的域field,get和set,以及修饰符范围ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型类必须是非final修饰的final修饰的类比如String,Integer等会跑出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}/*** 缓存处理* param factory* return*/Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializerString redisSerializer new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题ObjectMapper om new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化解决乱码的问题,过期时间600秒RedisCacheConfiguration config RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}
五、注解缓存
spring缓存注解
从3.1开始Spring引入了对Cache的支持。其使用方法和原理都类似于Spring对事务管理的支持。Spring Cache是作用在方法上的其核心思想是这样的当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中等到下次利用同样的参数来调用该方法时将不再执行该方法而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。
使用Spring Cache需要我们做两方面的事
1. 声明某些方法使用缓存
2. 配置Spring对Cache的支持
和Spring对事务管理的支持一样Spring对Cache的支持也有基于注解和基于XML配置两种方式。下面我们先来看看基于注解的方式。基于配置的自己私下去了解即可
基于注解的支持
Cacheable
Cacheable可以标记在一个方法上也可以标记在一个类上。
当标记在一个方法上时表示该方法是支持缓存的当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法Spring会在其被调用后将其返回值缓存起来以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果而不需要再次执行该方法。
Cacheable 的作用 主要针对方法配置能够根据方法的请求参数对其结果进行缓存
Cacheable可以指定三个属性value、key和condition。 参数 解释 example value 缓存的名称在 spring 配置文件中定义必须指定至少一个 例如: Cacheable(value”mycache”) Cacheable(value{”cache1”,”cache2”} key 缓存的 key可以为空如果指定要按照 SpEL 表达式编写如果不指定则缺省按照方法的所有参数进行组合 Cacheable(value”testcache”,key”#userName”) condition 缓存的条件可以为空使用 SpEL 编写返回 true 或者 false只有为 true 才进行缓存 Cacheable(value”testcache”,condition”#userName.length()2”)
a. value属性指定Cache名称
value其表示当前方法的返回值是会被缓存在哪个Cache上的对应Cache的名称。其可以是一个Cache也可以是多个Cache当需要指定多个Cache时其是一个数组。 Cacheable(cache1)//Cache是发生在cache1上的public User find(Integer id) {returnnull;}Cacheable({cache1, cache2})//Cache是发生在cache1和cache2上的public User find(Integer id) {returnnull;}
b. 使用key属性自定义key
key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时Spring将使用默认策略生成key。我们这里先来看看自定义策略
自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。
Cacheable(valueusers, key#id)public User find(Integer id) {return null;}// p param 参数 0 Cacheable(valueusers, key#p0)public User find(Integer id) {returnnull;}Cacheable(valueusers, key#user.id)public User find(User user) {returnnull;}Cacheable(valueusers, key#p0.id)public User find(User user) {returnnull;}
除了上述使用方法参数作为key之外Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。 属性名称 描述 示例 methodName 当前方法名 #root.methodName method 当前方法 #root.method.name target 当前被调用的对象 #root.target targetClass 当前被调用的对象的class #root.targetClass args 当前方法参数组成的数组 #root.args[0] caches 当前被调用的方法使用的Cache #root.caches[0].name 当我们要使用root对象的属性作为key时我们也可以将“#root”省略因为Spring默认使用的就是root对象的属性。如 Cacheable(value{users, xxx}, keycaches[1].name)public User find(User user) {returnnull;}
condition属性指定发生的条件
有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的当为true时表示进行缓存处理当为false时表示不进行缓存处理即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存。 Cacheable(value{users}, key#user.id, condition#user.id%20)public User find(User user) {System.out.println(find user by user user);return user;}
CachePut
在支持Spring Cache的环境下对于使用Cacheable标注的方法Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素如果存在就不再执行该方法而是直接从缓存中获取结果进行返回否则才会执行并将返回结果存入指定的缓存中。CachePut也可以声明一个方法支持缓存功能。与Cacheable不同的是使用CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果而是每次都会执行该方法并将执行结果以键值对的形式存入指定的缓存中。
一般使用在保存更新方法中。
CachePut也可以标注在类上和方法上。使用CachePut时我们可以指定的属性跟 Cacheable是一样的。 Cacheable(cacheNames user, key #id)//每次都会执行方法并将结果存入指定的缓存中public User find(Integer id) {return null;}
CacheEvict
CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与Cacheable对应的属性类似。即value表示清除操作是发生在哪些Cache上的对应Cache的名称key表示需要清除的是哪个key如未指定则会使用默认策略生成的keycondition表示清除操作发生的条件。下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。
1、 allEntries属性
allEntries是boolean类型表示是否需要清除缓存中的所有元素。默认为false表示不需要。当指定了allEntries为true时Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素这比一个一个清除元素更有效率。
CacheEvict(valueusers,key #id, allEntriestrue)
public void delete(Integer id) {System.out.println(delete user by id: id);
}
2、 beforeInvocation属性
清除操作默认是在对应方法成功执行之后触发的即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间当我们指定该属性值为true时Spring会在调用该方法之前清除缓存中的指定元素。
CacheEvict(valueusers,key #id, beforeInvocationtrue)
public void delete(Integer id) {System.out.println(delete user by id: id);
}
六、springboot基于注解的redis缓存
1.开启注解缓存 2. 添加缓存 3. 测试
第一次访问控制台会打印数据 缓存之后清空控制台再次访问直接通过缓存获取