深入理解Spring Redis的使用 (二)、RedisTemplate事务支持、序列化

上一篇文章我们讲解了RedisTemplate的基本使用,通过RedisCallback来获得connection,然后去操作Redis。网上的教程,大部分也都是这样的操作。

这个类似于HibernateTemplate里面提供的executeWithNativeSession方法,是Java中的一种同步回调机制。在方法的前后,系统替我们打开关闭连接,设置事务等。

RedisTemplate api详解

1. RedisTemplate的事务

    private boolean enableTransactionSupport = false;
    private boolean exposeConnection = false;
    private boolean initialized = false;
    private boolean enableDefaultSerializer = true;
    private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();

    private RedisSerializer keySerializer = null;
    private RedisSerializer valueSerializer = null;
    private RedisSerializer hashKeySerializer = null;
    private RedisSerializer hashValueSerializer = null;
    private RedisSerializer<String> stringSerializer = new StringRedisSerializer();

    private ScriptExecutor<K> scriptExecutor;

    // cache singleton objects (where possible)
    private ValueOperations<K, V> valueOps;
    private ListOperations<K, V> listOps;
    private SetOperations<K, V> setOps;
    private ZSetOperations<K, V> zSetOps;

enableTransactionSupport:是否启用事务支持。我们在代码中搜索下用到这个变量的地方,会看到,在调用RedisCallback之前,有一行代码是如果启用事务支持,那么conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport),也就是说,系统自动帮我们拿到了事务中绑定的连接。可以在一个方法的多次对Redis增删该查中,始终使用同一个连接。但是,即使使用了同样的连接,没有进行connection.multi()和connection.exec(),依然是无法启用事务的。

我没有仔细的查阅代码,但是可以知道的是,Spring已经对这个,给了我们一个更好的支持:@Transactional 

在调用RedisTempalte中的execute()方法的地方,加入这个注解(是spring包下面提供的,不要引用成rt包下的注解),能让这个方法中的所有execute,自动加入multi()以及异常的回滚或者是正常运行时候的提交!

2. RedisTempalte的Serializer

用过jedis操作的都知道,所有connection的操作方法,都是传入字节数组。那么,将一个对象和字节相互转换,就需要通过序列化和反序列化。

模版方法中,Spring提供了默认的StringSerializer和JdkSerializer,第一个很简单,就是通过String.getBytes()来实现的。而且在Redis中,所有存储的值都是字符串类型的。所以这种方法保存后,通过Redis-cli控制台,是可以清楚的查看到我们保存了什么key,value是什么。但是对于JdkSerializationRedisSerializer来说,这个序列化方法就是Jdk提供的了。首先要求我们要被序列化的类继承自Serializeable接口,然后通过,然后通过Jdk对象序列化的方法保存。(注:这个序列化保存的对象,即使是个String类型的,在redis控制台,也是看不出来的,因为它保存了一些对象的类型什么的额外信息,)

这么一长串,其实就是一个int类型的123。

keySerializer:这个是对key的默认序列化器。默认值是StringSerializer。

valueSerializer:这个是对value的默认序列化器,默认值是取自DefaultSerializer的JdkSerializationRedisSerializer。

hashKeySerializer:对hash结构数据的hashkey序列化器,默认值是取自DefaultSerializer的JdkSerializationRedisSerializer。

hashValueSerializer:对hash结构数据的hashvalue序列化器,默认值是取自DefaultSerializer的JdkSerializationRedisSerializer。

除此之外,我们在该类中,还发现了valueOps和hashOps等操作类,这是spring给我们提供的可以直接使用来操作Redis的类,非常方便。下一篇我们将讲解这些类。

时间: 2024-10-31 15:54:18

深入理解Spring Redis的使用 (二)、RedisTemplate事务支持、序列化的相关文章

分布式缓存技术redis学习系列----深入理解Spring Redis的使用

关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么优秀的一个框架.Spring-data-redis为spring-data模块中对redis的支持部分,简称为"SDR",提供了基于jedis客户端API的高度封装以及与spring容器的整合,事实上jedis客户端已经足够简单和轻量级,而spring-data-redis反而具有&quo

深入理解Spring Redis的使用 (一)、Spring Redis基本使用

关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么优秀的一个框架.这里,我们就对比之前对spring orm中对hibernate的使用,来理解使用spring redis的使用.(本文章不做redis基本命令使用的讲解) 1. Redis使用场景 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Va

深入理解Spring Redis的使用 (七)、Spring Redis 使用 jackson序列化 以及 BaseDao代码

之前在介绍Spring Redis进行存储的时候,都是通过RedisTemplate中的defaultSerializer,即JdkSerializationRedisSerializer.通过Jdk的序列化比较简单,但是有时候线上调试的时候通过控制台查看,完全看不出来存储了什么东西.而且在空间占用和性能上,相比Jackson,完全没有优势. 有过两次线上出问题,定位的时候知道缓存有错,却不知道到底出在那个缓存的字段上,调试非常不方便.于是序列化统统换成了Jackson. 代码如下: impor

深入理解Spring Redis的使用 (三)、使用RedisTemplate的操作类访问Redis

上一篇说了RedisTemplate对注解事务的支持,以及提供的序列化器. 事务需要开启enableTransactionSupport,然后使用@transactional注解,里面直接通过回调的connection,就不需要自己进行multi和exec的事务开启提交了.但是通过回调去获取connection,完全没有达到一个模版类的功能.所以这篇我们会讲下几种Operations接口提供的方法. private ValueOperations<K, V> valueOps; private

深入理解Spring Redis的使用 (四)、RedisTemplate执行Redis脚本

对于Redis脚本使用过的同学都知道,这个主要是为了防止竞态条件而用的.因为脚本是顺序执行的.(不用担心效率问题)比如我在工作用,用来设置考试最高分. 如果还没有用过的话,先去看Redis脚本的介绍,发送脚本,缓存脚本,发送sha1执行脚本,以及基本的lua脚本的语法. 1. Redis脚本的使用场景 在一些缓存的设置中,经常会出现竞态条件,由于并发导致数据有误.比如大家熟知的++操作.我们自己通过Redis实现++的话,很容易在并发下出现误差.所以Redis提供了incr函数.我在设置最高分的

深入理解Spring Redis的使用 (八)、Spring Redis实现 注解 自动缓存

项目中有些业务方法希望在有缓存的时候直接从缓存获取,不再执行方法,来提高吞吐率.而且这种情况有很多.如果为每一个方法都写一段if else的代码,导致耦合非常大,不方便后期的修改. 思来想去,决定使用自动注解+Spring AOP来实现. 直接贴代码. 自定义注解类: package com.ns.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import

深入理解Spring Redis的使用 (九)、通过Redis 实现 分布式锁 的 BUG,以及和数据库加锁的性能测试

在多节点的项目中,经常要涉及到某些方法加锁的控制.而这个时候,简单易用的synchronized已经不能满足多节点的部署结构. 之前在项目中,用的比较多的是数据库的更新锁:for udpate.但是这个有个缺点,就是对于本来就容易出现瓶颈的数据库,造成了更大的压力.同时,如果是锁表的语句,同时表数据量特别大,基本服务器直接宕机了. 所以,决定绕开数据库,直接使用Redis来实现分布式锁.查了下资料,找到一些文章,思路都一致: http://www.jeffkit.info/2011/07/100

SpringBoot系列: 理解 Spring 的依赖注入(二)

==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @Bean, 另一个是 @Component 和它的子类 (包括 @Service/@Controller/@Repository/@Configuration), Spring 容器中 bean 名生成规则分两大类, 分别是: 一. @Component 和它的子注解是用来注解 Class 的. 这些

深入理解Spring Redis的使用 (九)、通过Redis 实现 分布式锁

多节点的部署中,对锁的控制,参考: http://www.jeffkit.info/2011/07/1000/ 直接贴上代码实现,同上一篇文章一样,都是基于AOP 定义注解,标志切入点: package com.ns.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import jav