RedisTemplate:execute与executePipelined

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 本文主要介绍了org.springframework.data.redis中RedisTemplate的execute与executePipelined的区别,简要说明了executePipelined为什么会报出Callback cannot return a non-null value as it gets overwritten by the pipeline的异常。

1.官网注释

execute
@Nullable
public <T> T execute(RedisCallback<T> action)
  • Description copied from interface: RedisOperations
    Executes the given action within a Redis connection. Application exceptions thrown by the action object get propagated to the caller (can only be unchecked) whenever possible. Redis exceptions are transformed into appropriate DAO ones. Allows for returning a result object, that is a domain object or a collection of domain objects. Performs automatic serialization/deserialization for the given objects to and from binary data suitable for the Redis storage. Note: Callback code is not supposed to handle transactions itself! Use an appropriate transaction manager. Generally, callback code must not touch any Connection lifecycle methods, like close, to let the template do its work.

Specified by:
execute in interface RedisOperations

  • Type Parameters:
    T - return type
  • Parameters:
    • callback object that specifies the Redis action. Must not be null.
  • Returns:
  1. result object returned by the action or null

从以上注释可知,该方法执行给定的Action在一次redis连接中。执行完成之后可以返回多个结果(List)。但是需要注意的是,它本身不支持解决事务,如果需要多个操作为一个事务,需要使用专门的TransactionSynchronizationManager。当然了,如果我们一系列操作都是查询,不需要开启事务,使用这个很好。

executePipelined
public List<Object> executePipelined(SessionCallback<?> session)
  • Description copied from interface: RedisOperations
    Executes the given Redis session on a pipelined connection. Allows transactions to be pipelined. Note that the callback cannot return a non-null value as it gets overwritten by the pipeline.

Specified by:
executePipelined in interface RedisOperations

  • Parameters:
    • Session callback
  • Returns:
  1. of objects returned by the pipeline

所以,两者的区别就在注释中一目了然了。executePipelined是可以允许我们执行事务的。executePipelined还有一个需要注意的点,就是虽然重写了回调函数,但是回调函数还是有可能返回空值的。注释里说是在被管道覆盖的时候,这是在说什么呢?

2.executePipelined

public List<Object> executePipelined(final SessionCallback<?> session, final RedisSerializer<?> resultSerializer) {
        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(session, "Callback object must not be null");

        RedisConnectionFactory factory = getConnectionFactory();
        // bind connection
        RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
        try {
            return execute(new RedisCallback<List<Object>>() {
                public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                    connection.openPipeline();
                    boolean pipelinedClosed = false;
                    try {
                        Object result = executeSession(session);
                        if (result != null) {
                            throw new InvalidDataAccessApiUsageException(
                                    "Callback cannot return a non-null value as it gets overwritten by the pipeline");
                        }
                        List<Object> closePipeline = connection.closePipeline();
                        pipelinedClosed = true;
                        return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
                    } finally {
                        if (!pipelinedClosed) {
                            connection.closePipeline();
                        }
                    }
                }
            });
        } finally {
            RedisConnectionUtils.unbindConnection(factory);
        }
    }

这里判断了executeSession的返回结果是否非空,这个函数最终会调用下面这个函数:

    /**
     * Executes all the given operations inside the same session.
     * 
     * @param operations Redis operations
     * @return return value
     */
    <K, V> T execute(RedisOperations<K, V> operations) throws DataAccessException;

正如注释中所说的那样,这个函数会执行当前会话中的所有的operation,以判断是否已经有了操作,保证该事务不被其它操作干扰。

相关文章
|
缓存 NoSQL 架构师
Redis 三种批量查询技巧,高并发场景下的利器
在高并发场景下,巧妙地利用缓存批量查询技巧能够显著提高系统性能。 在笔者看来,熟练掌握细粒度的缓存使用是每位架构师必备的技能。因此,在本文中,我们将深入探讨 Redis 中批量查询的一些技巧,希望能够给你带来一些启发。
Redis 三种批量查询技巧,高并发场景下的利器
|
数据安全/隐私保护
ES、Kibana 8.0安装
ES、Kibana 8.0安装
317 0
|
SQL XML 关系型数据库
Mybatis-Plus通过SQL注入器实现真正的批量插入
Mybatis-Plus通过SQL注入器实现真正的批量插入
6285 0
Mybatis-Plus通过SQL注入器实现真正的批量插入
|
消息中间件 中间件 Kafka
Kafka - TimeoutException: Expiring 1 record(s) for art-0:120001 ms has passed since batch creation
Kafka - TimeoutException: Expiring 1 record(s) for art-0:120001 ms has passed since batch creation
1383 0
|
缓存 NoSQL Java
SpringBoot中RedisCluster的scan命令实践
线上环境redis key过期一直很头疼,自动过期用户可能会给用户展示过期数据无法忍受,可是又无法掌握固定的key,redis给我们提供了高性能的scan操作,可千万不能用keys * 了! SpringBoot2.0升级使用lettuce替换了jedis为默认的reids连接工具。
3115 0
|
缓存 NoSQL Java
阿里巴巴开源的通用缓存访问框架JetCache介绍
JetCache是由阿里巴巴开源的通用缓存访问框架,如果你对Spring Cache很熟悉的话,请一定花一点时间了解一下JetCache,它更好用。JetCache可以做类似Spring Cache的注解式缓存,支持TTL、多级缓存、分布式自动刷新,也提供类似JSR107规范的Cache API。
12999 1
|
SQL Java 关系型数据库
Mybatis:通过on duplicate key update实现批量插入或更新
Mybatis:通过on duplicate key update实现批量插入或更新
Mybatis:通过on duplicate key update实现批量插入或更新
|
3月前
|
应用服务中间件 Linux 测试技术
Tomcat启动错误:组件启动失败StandardEngine[Catalina].StandardHost[localhost].StandardContext[]
解决此类问题需要系统地排查和分析,有时候甚至需要根据应用的具体情况定制化解决方案。注意的是,如果问题涉及到复杂的应用逻辑或第三方库,那么可能需要深入到具体的应用代码和库文档中查找原因。最后,保持软件环境的更新也是预防这类问题的好习惯,因为新版本的软件通常会修复旧版本中的已知错误。
393 12
|
NoSQL Java Redis
在 Spring 中操作 Redis
本文详细介绍了在Spring框架中如何通过引入依赖、配置文件、使用StringRedisTemplate类以及执行原生命令等方式来操作Redis数据库,并提供了对String、List、Set、Hash和ZSet数据类型的操作示例。
359 0
在 Spring 中操作 Redis
|
NoSQL Redis
RedisTemplate.opsForSet()用法简介并举例
RedisTemplate.opsForSet()用法简介并举例
1184 2