StringRedisTemplate中execute、executePipelined原理及使用

Redis事务
本质:一组命令的集合 要么一起成功 要么一起失败,一个事务中的所有命令都会被序列化,在事务执行过程中会按照顺序执行

注意:
Redis单条命令是保证原子性的,但是事务是不保证原子性的
Redis没有隔离级别的概念
开启事务:multi
执行事务:exec

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 2
QUEUED
127.0.0.1:6379> set k2 3
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> set k3 1
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) "2"
4) OK
127.0.0.1:6379>   

RedisTemplate中如何开启并执行事务?

public void testMultiFailure() {
	// 开启事务支持,在同一个 Connection 中执行命令
    stringRedisTemplate.setEnableTransactionSupport(true);
    
	stringRedisTemplate.multi();
	stringRedisTemplate.opsForValue().set(“name”, “qinyi”);
	stringRedisTemplate.opsForValue().set(“gender”, “male”);
	stringRedisTemplate.opsForValue().set(“age”,19);
	stringRedisTemplate.exec()
	System.out.println();
}

更常见的写法仍是采用 RedisTemplate 的默认配置,即不开启事务支持。
可以通过使用 SessionCallback,该接口保证其内部所有操作都是在同一个Session中。

@Test
@SuppressWarnings("all")
public void testSessionCallback() {

    SessionCallback<Object> callback = new SessionCallback<Object>() {
        @Override
        public Object execute(RedisOperations operations) throws DataAccessException {
            operations.multi();
            operations.opsForValue().set("1", "11");
            operations.opsForValue().set("2", "22");
            operations.opsForValue().set("3", "33");
            return operations.exec();
        }
    };

    System.out.println(stringRedisTemplate.execute(callback));
}

execute

用于执行一个 Redis 命令,支持单个 Redis 命令以及事务操作。

官网解释:
在这里插入图片描述
黑马头条中的一个小案例
扫描主键,获取匹配partten的主键对应的值

    /**
     * 扫描主键,建议使用
     * @param patten
     * @return
     */
    public Set<String> scan(String patten){
        Set<String> keys = stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> result = new HashSet<>();
            try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
                    .match(patten).count(10000).build())) {
                while (cursor.hasNext()) {
                    result.add(new String(cursor.next()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        });
        return  keys;
    }

这里用的是RedisCallback。
RedisCallback 和 SessionCallback 都是 Spring Data Redis 提供的两种回调接口,用于执行 Redis 操作。
参考链接: https://juejin.cn/post/7234103673344262199

  • RedisCallback:表示一个针对 Redis 的操作回调,包括连接、命令执行和连接释放等过程。
  • SessionCallback:用于 Redis 事务,表示一个针对 Redis 的事务操作回调,包括事务的开始、命令的执行和事务的提交或者回滚等过程。

前者执行单个命令,后者执行事务

executePipeline

用于执行多个 Redis 命令
将所有命令缓存在管道中,最终一次性发送给 Redis 服务器。这样可以减少与 Redis 服务器的通信次数,提高命令的执行效率和吞吐量。

官网案例

//pop a specified number of items from a queue
List<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;
    }
});

黑马头条案例

    /**
     * 管道技术,提高性能
     * @param type
     * @param values
     * @return
     */
public List<Object> refreshWithPipeline(String future_key,String topic_key,Collection<String> values){

        List<Object> objects = stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
            @Nullable
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                StringRedisConnection stringRedisConnection = (StringRedisConnection)redisConnection;
                String[] strings = values.toArray(new String[values.size()]);
                stringRedisConnection.lPush(topic_key,strings);
                stringRedisConnection.zRem(future_key,strings);
                return null;
            }
        });
        return objects;
    }
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值