使用Javaredistemplateredis管道(pipeline)批量查询时,往往会遇到一个棘手的问题:即使keys集合包含有效数据,Redis中也有相应的数据,但返回结果都是null。这是因为Redistemplate的管道操作特性。
问题根源:
Redistemplate的管道操作将批量向服务器发送多个Redis命令,但不会立即返回结果。所有命令的执行结果将被缓存,直到调用executepipelined方法,并返回包含每个命令响应的列表。 因此,Rediscalback或Sessioncalback的直接处理结果无效,因为Redis的响应尚未返回。
错误代码示例 (类似于原文中的错误代码):
以下代码片段演示了错误的处理方法,试图在管道操作中处理结果:
// 错误示例:试着在pipeline内部处理结果 public <T> List<T> batchGetList(Collection<String> keys) { List<T> list = new ArrayList<>(); // ... (省略一些代码) ... List<Object> results = redisTemplate.executePipelined(new RedisCallback<Object>() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { for (String key : keys) { byte[] bytes = connection.get(redisTemplate.getKeySerializer().serialize(key)); T obj = (T) redisTemplate.getValueSerializer().deserialize(bytes); // 错误:结果还没有回来 list.add(obj); } return null; } }); return list; }
正确的解决方案:
正确的方法是在executePipelined之后处理结果列表。 以下代码显示了正确的处理方法:
public <T> List<T> batchGetList(Collection<String> keys) { if (CollectionUtil.isEmpty(keys)) { return new ArrayList<>(); } List<Object> results = redisTemplate.executePipelined((RedisConnection connection) -> { RedisSerializer<String> keySerializer = redisTemplate.getKeySerializer(); for (String key : keys) { connection.get(keySerializer.serialize(key)); } return null; // executepipelined需要返回nulll }); // 管道执行后处理结果 List<T> resultList = results.stream() .map(result -> { if (result != null) { return (T) redisTemplate.getValueSerializer().deserialize((byte[]) result); } else { return null; // 处理null结果 } }) .collect(Collectors.toList()); return resultList; }
该代码首先执行管道操作,然后通过results列表,使用redistemplatetetee.getValueSerializer()反序列化每个byte[]的结果。 为了避免Nulllpointerexception,添加了null结果的处理。 确保您的Redistemplate配备了正确的序列化器。
关键点:
- executePipelined返回值: executepipelined方法返回列表,包含所有命令执行结果。 有必要在lambda表达式中返回null。
- 结果处理: executePipelined调用后必须进行结果处理。
- 序列化器: 确保Redistemplate配备正确的键和值序列化器,以匹配您存储在Redis中的数据类型。
- 空值处理: 处理results列表中的null值,防止异常。
通过以上改进,Redistemplate管道批量查询返回空值的问题可以得到有效解决。 请记住,管道操作效率的提高来自于批量执行,结果处理必须在批量操作完成后进行。
以上是Redistemplate在使用Redistemplate进行批量查询时,为什么返回的结果是空值?详情请关注图灵教育其他相关文章!
