JedisDataException: Please close pipeline or multi block before calling this method

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: JedisDataException: Please close pipeline or multi block before calling this method

错误原因

transaction错误使用

pipeline错误使用


具体分析

transaction错误使用
  • Redis事务的执行结果是在exec之后才统一返回,所以Jedis会用一个Response对象最为事务对象transaction的执行放回值。如果我们在transaction执行exec方法之前调用response对象的get方法会出现异常:
  • Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.
  • 更多Redis事务操作,请移步:https://blog.csdn.net/fly910905/article/details/78981084
pipeline错误使用

1.异常堆栈

redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.


2.异常描述:

在pipeline.sync()执行之前,通过response.get()获取值,在pipeline.sync()执行前,命令没有执行(可以通过monitor做验证),下面代码就会引起上述异常

1. Jedis jedis = new Jedis("127.0.0.1", 6379);
2. Pipeline pipeline = jedis.pipelined();
3. pipeline.set("hello", "world"); 
4. pipeline.set("java", "jedis");
5. 
6. Response<String> pipeString = pipeline.get("java");
7. //这个get必须在sync之后,如果是批量获取值建议直接用List<Object> objectList = pipeline.syncAndReturnAll();
8. System.out.println(pipeString.get());
9. //命令此时真正执行
10. pipeline.sync();


Jedis中Reponse中get()方法,有个判断:如果set=false就会报错,而response中的set初始化为false.

public T get() {
  // if response has dependency response and dependency is not built,
  // build it first and no more!!
  if (dependency != null && dependency.set && !dependency.built) {
    dependency.build();
  }
  if (!set) {
    throw new JedisDataException(
        "Please close pipeline or multi block before calling this method.");
  }
  if (!built) {
    build();
  }
  if (exception != null) {
    throw exception;
  }
  return response;
}


pipeline.sync()会每个结果设置set=true。

public void sync() {
  if (getPipelinedResponseLength() > 0) {
    List<Object> unformatted = client.getAll();
    for (Object o : unformatted) {
      generateResponse(o);
    }
  }
}


其中generateResponse(o):

protected Response<?> generateResponse(Object data) {
  Response<?> response = pipelinedResponses.poll();
  if (response != null) {
    response.set(data);
  }
  return response;
}


其中response.set(data);

public void set(Object data) {
    this.data = data;
    set = true;
}


3.解决方法:

实际上对于批量结果的解析,建议使用pipeline.syncAndReturnAll()来实现,下面操作模拟了批量hgetAll

/**
* pipeline模拟批量hgetAll
* @param keyList
* @return
*/
public Map<String, Map<String, String>> mHgetAll(List<String> keyList) {
// 1.生成pipeline对象
Pipeline pipeline = jedis.pipelined();
// 2.pipeline执行命令,注意此时命令并未真正执行
for (String key : keyList) {
  pipeline.hgetAll(key);
}
// 3.执行命令 syncAndReturnAll()返回结果
List<Object> objectList = pipeline.syncAndReturnAll();
if (objectList == null || objectList.isEmpty()) {
  return Collections.emptyMap();
}
// 4.解析结果
Map<String,Map<String, String>> resultMap = new HashMap<String, Map<String,String>>();
for (int i = 0; i < objectList.size(); i++) {
  Object object = objectList.get(i);
  Map<String, String> map = (Map<String, String>) object;
  String key = keyList.get(i);
  resultMap.put(key, map);
}
return resultMap;
}


4.处理人:

修改业务代码。


参考来源:https://yq.aliyun.com/articles/236384?spm=a2c4e.11155435.0.0.e21e2612uQAVoW#cc1



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
9月前
|
Serverless
attempt to delete a method
attempt to delete a method
127 1
|
6月前
|
Web App开发 前端开发
【前端异常】Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
【前端异常】Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
464 0
|
XML SQL 数据库
Error getting generated key or setting result to parameter object.必须执行该语句才能获得结果。
Error getting generated key or setting result to parameter object.必须执行该语句才能获得结果。
|
10月前
|
Java 关系型数据库 MySQL
10. 成功解决:io.netty.channel.ChannelPipelineException: ***Handler is not a @Sharable handler, so can't be added or removed multiple times.
使用 SpringBoot 集成 Netty 时,报如下错误:io.netty.channel.ChannelPipelineException: ***Handler is not a @Sharable handler, so can't be added or removed multiple times.
334 0
|
Java 应用服务中间件 Linux
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
1280 0
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
没解决:RuntimeWarning: tp_compare didn't return -1 or -2 for exception
没解决:RuntimeWarning: tp_compare didn't return -1 or -2 for exception
67 0
|
Java Android开发
Bad method handle type 7异常解决
在利用androidx版本写demo时,在添加了一些依赖后,遇到了`java.lang.ClassNotFoundException`bug,这就很奇怪了,我就添加rxjava3的依赖,就给我报这个错误。
|
索引
ES报错:“type“=>“cluster_block_exception“, “reason“=>“blocked by: [FORBIDDEN/12/index read-only / allow
ES报错:“type“=>“cluster_block_exception“, “reason“=>“blocked by: [FORBIDDEN/12/index read-only / allow
273 0
ES报错:“type“=>“cluster_block_exception“, “reason“=>“blocked by: [FORBIDDEN/12/index read-only / allow
​Error -4075: File not found. An error occurred merging module <MODULENAME> for feature <FEATURENAME>.
​Error -4075: File not found. An error occurred merging module <MODULENAME> for feature <FEATURENAME>.
87 0
​Error -4075: File not found. An error occurred merging module <MODULENAME> for feature <FEATURENAME>.
multi-thread handling for batch request
Created by Wang, Jerry, last modified on Feb 13, 2017
66 0
multi-thread handling for batch request

热门文章

最新文章