Spring Data Redis -----笔记4
来源:互联网 发布:网络信贷 编辑:程序博客网 时间:2024/06/13 19:38
继续码字
5.10.Redis Transactions(Redis的事务)
Redis通过命令multi,exec和discard对事务的支持。这些操作命令在RedisTemplate也有对应的方法。然而,RedisTemplate它不能保证一个事务的所有操作都在相同连接中完成。
Spring Data Redis 为用户提供SessionCallback接口,它能保证一个事务的所有操作都在相同的连接中完成。例如:
//execute a transactionList<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() { public List<Object> execute(RedisOperations operations) throws DataAccessException { operations.multi(); operations.opsForSet().add("key", "value1"); // This will contain the results of all ops in the transaction return operations.exec(); }});System.out.println("Number of items added to set: " + txResults.get(0));
提示:
在版本1.1的RedisConnection和RedisTemplate的方法exec最大的改变是,在先前的方法直接返回执行事务的结果。这就意味着这个数据类型经常不同于RedisConnection返回的结果。举个例子,zAdd返回一个boolean值表明这个元素已经添加到有序集合中。但是大多数连接器返回时一个long型的值,Spring Data Redis需要进行转换。其他公共不同的是对于set操作大多数连接器返回一个状态作为响应(通常是字符串“OK”)。这些返回是Spring Data Redis典型废弃的形式。在1.1版本之前。这些转换都不会在exec执行。也就是Redis不会反序列这个结果。因为这里经常包含原生的字节数组。如果这个行为改变你的应用,你可以在RedisConnectionFactory设置convertPipelineAndTxResults为false来禁止这种行为。
5.10.1.@Transactional Support(注解支持)
事务支持在默认情况的是关闭的,你需要为每个RedisTemplate显式开启,通过设置setEnableTransactionSupport(true).这样将会强制绑定到当前的RedisConnection,它对应的线程会触发MULTI。如果事务执行过程没有错误,EXEC将会被调用。否则DISCARD被调用。一旦在MULTI中,RedisConnection队列化所有写的操作和所有读的操作,例如KEYS将会更新到RedisConnection中。
/** Sample Configuration **/@Configurationpublic class RedisTxContextConfiguration { @Bean public StringRedisTemplate redisTemplate() { StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory()); // explicitly enable transaction support template.setEnableTransactionSupport(true); return template; } @Bean public PlatformTransactionManager transactionManager() throws SQLException { return new DataSourceTransactionManager(dataSource()); } @Bean public RedisConnectionFactory redisConnectionFactory( // jedis, lettuce, srp,... ); @Bean public DataSource dataSource() throws SQLException { // ... }}
/** Usage Constrainsts **/// executed on thread bound connectiontemplate.opsForValue().set("foo", "bar");// read operation executed on a free (not tx-aware)connection template.keys("*");// returns null as values set within transaction are not visibletemplate.opsForValue().get("foo");
5.11.Pipelining(管道线)
Redis支持pipelining,它涉及发送多个命令到服务器不需要每次等待回复。最后一步读取返回数据。Pipelining 单行发送多个命令来提高性能,例如添加多个元素到相同的List集合中。
Spring Data Redis提供多个RedisTemplate方法去执行pipeline命令。如果你不关心pipeline的执行结果,你可以使用标准的execute方法,在为pipeline参数传入true。这行executePipelined方法将会提供一个RedisCallback或者SessionCallback回调,然后返回结果,例如:
//pop a specified number of items from a queueList<Object> results = stringRedisTemplate.executePipelined( new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { StringRedisConnection stringRedisConn = (StringRedisConnection)connection; for(int i=0; i< batchSize; i++) { stringRedisConn.rPop("myqueue"); } return null; }});
以上例子展示的pipeline队列批量左边出栈。这个结果list集合包含所有的出栈选项。在返回之前RedisTemplate使用它值,hash key,和hash value序列化器去返回序列化所有结果,所以在上述案例中返回的是字符串类型。除此之外,executePipelined方法允许你为pipeline结果执行自定义序列号器。
注意 当这个值被遗弃,取而代之的是pipeline命令执行的结果,这个RedisCallback返回值的结果要求为null,
5.12.Redis Scripting(Redis 脚本)
Redis 2.6及以上版本支持Lua脚本,它需要使用的命令是eval和evalsha。Spring Data Redis 为执行脚本提供高级抽象,它可以处理序列化和自动使用Redis脚本缓存。
RedisTemplate的execute方法可以执行脚本。RedisTemplate使用一个配置ScriptExecutor去执行提供的脚本。默认情况下。这个ScriptExecutor关心的序列化提供的keys和参数,以及反序列化脚本的结果。这些工作都是RedisTemplate 的key和value序列化器所在做。有一个额外的execute方法是允许你为脚本参数和结果自定义序列化器。
这个默认的ScriptExecutor通过SHA1加密脚本和尝试第一次去运行evalsha命令来优化性能,如果Redis 脚本缓存不存在,它将会回调eval命令。
这里有一个例子使用Luau脚本来执行一个公共的“check-and-set”场景。这是一个理想使用案例。它要求执行一系列的命令是原子性。一个命令的行为将会被另个结果所影响。
@Beanpublic RedisScript<Boolean> script() { DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<Boolean>(); redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("META-INF/scripts/checkandset.lua"))); redisScript.setResultType(Boolean.class);}
public class Example { @Autowired RedisScript<Boolean> script; public boolean checkAndSet(String expectedValue, String newValue) { return redisTemplate.execute(script, Collections.singletonList("key"), expectedValue, newValue); }}
-- checkandset.lua local current = redis.call('GET', KEYS[1]) if current == ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]) return true end return false
以上xml配置一个DefaultRedisScript指向了一个文件名为checkandset.lua,它将期望返回一个boolean值,这个脚本的结果类型应该Long型、Boolean、List、或者反序列化值类型。如果这个脚本返回抛出的状态(例如“OK”),它的返回类型将会为null。一个理想在你的应用上下文配置一个单个实例化DefaultRedisScript对象,在每次脚本执行的时候就可以避免再次计算SHA1。
以上CheckAndSet方法将会在一个SessionCallback作为事务或pipeline一个部分执行脚本,详情参考RedisTransations和Pipelining。
这个脚本执行允许你制定定时任务,关于定时任务参考Spring框架文档。
5.13.Support Classes(支持类)
在包下org.springframework.data.redis.support 提供众多可重复利用的组件,它依赖于Redis作为存储端。当前包下包含众多基于JDK-based接口(实现Redis最顶层,例如原子计数)和JDK集合。
原子性计数使得包装Redis key更加容易,集合将会很容易管理Redis keys,只要使用最小的存储暴露或API接口泄露:在特定RedisSet 和RedisZSet接口提供容易获取set操作,例如交集、并集。当RedisList实现了List,Queue和Deque关联最高Redis,暴露的存储 FIFO(先进先出)LIFO(后进先出)或者固定集合,如下最小配置:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="queue" class="org.springframework.data.redis.support.collections.DefaultRedisList"> <constructor-arg ref="redisTemplate"/> <constructor-arg value="queue-key"/> </bean></beans>
public class AnotherExample { // injected private Deque<String> queue; public void addTag(String tag) { queue.push(tag); }}
5.13.1. Support for Spring Cache Abstraction(支持Spring缓存抽象)
Spring Redis 提供为缓存抽象化的实现,在包org.springframework.data.redis.cache下。为了使用Redis 作为一个支持的实现。在你配置文件中简单添加RedisCacheManager:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- turn on declarative caching --> <cache:annotation-driven /> <!-- declare Redis Cache Manager --> <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate"/></beans>
默认情况下无论Cache是否必须要,RedisCacheManager将会延迟初始化RedisCache。这是可以通过预定义一个包含名称Set集合来进行改变。
提示2:
默认情况RedisCacheManager不会支持事务,可以通过setTransactionAware去开启事务支持
提示3:
在默认情况下RedisCacheManager不会为缓存区域添加前缀key,它将会导致一个ZSET意外的增长。所以强烈推荐使用为缓存区域提供前缀key来避免意外的增长和潜在key冲突。
提示4:
在默认情况下RedisCache不会缓存一个value 为null的key。然而你可以通过显示确保null值被缓存。也就是RedisCacheManager去存储org.springframework.cache.support.NullValue作为占位符。
- Spring Data Redis -----笔记4
- Spring Data Redis ---笔记2
- Spring Data Redis ---笔记3
- Spring Data Redis Redis集群---笔记5
- Spring Data Redis ----Redis仓库----笔记6
- redis:spring-data-redis
- redis Jredis spring-data-redis
- spring data redis 操作redis
- Spring Data Redis (Redis Support)
- Spring Data Redis(Redis Transactions)
- Spring Data Redis(Redis Scripting)
- Spring Data Redis(Redis Cluster)
- Spring Data Redis(Redis Repositories)
- spring data redis 操作redis
- SPRING DATA - REDIS配置
- spring data redis试用
- SPRING DATA - REDIS配置
- SPRING DATA - REDIS配置
- unity学习日记:音频可视化
- 常见压缩工具和算法的压缩比率及资源消耗情况
- uva 11490
- Hibernate连接MySQL数据
- hdu2686 最大费用流
- Spring Data Redis -----笔记4
- RG_5
- Prim算法
- 卸载和安装LINUX上的JDK
- python第七周学习内容及测验作业
- 多线程的this.getName()与Thread.currentThread().getName为何有时不一样
- POJ 2184 Cow Exhibition(01背包)
- STL空间配置器
- 大数据学习笔记:Linux基础复习