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做验证),下面代码就会引起上述异常

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

为了实现Google Gmail注册功能,通常不会直接提供完整的源代码示例来创建Gmail账户。这是因为用户账户管理涉及敏感操作,应由官方服务处理以确保安全性和合规性。 然而,在开发与Gmail交互的应用程序时,可以利用OAuth 2.0协议授权流程来进行身份验证和访问控制[^3]。这允许第三方应用请求特定权限范围内的数据访问而无需知晓用户的密码。 对于希望集成Google登录或与其他Google服务互动的应用开发者来说,建议按照官方指南设置项目并启用必要的API接口: - 创建新的Google应用程序需前往Google API Console页面[^1]。 ```python import os from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] def main(): """Shows basic usage of the Gmail API. Lists the user's Gmail labels. """ creds = None flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) service = build('gmail', 'v1', credentials=creds) results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) if not labels: print('No labels found.') else: print('Labels:') for label in labels: print(label['name']) if __name__ == '__main__': main() ``` 此Python脚本展示了如何通过OAuth 2.0认证过程连接到Gmail API,并列出当前用户的标签列表作为简单演示。请注意,实际部署前还需要考虑更多细节配置以及错误处理机制等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云原生AI百宝箱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值