当前位置: 首页 > 面试题库 >

与Jedis客户进行交易时的Redis例外

东方高洁
2023-03-14
问题内容

为了避免在Redis通道中出现重复,我通过在Redis中设置索引来检查消息是否已经存在。以下是我的实现。但是,这是一个例外。

redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.
    at redis.clients.jedis.Response.get(Response.java:23)

这是实现。

          Jedis jedis = pool.getResource();

          String id = message.getId();
          Transaction transaction = jedis.multi();
          redis.clients.jedis.Response<java.lang.Boolean> response = transaction.sismember(ID_SET_REDIS_KEY, id);
          if (response != null && !response.get().booleanValue()) {
                //add it to the 
                transaction.sadd(ID_SET_REDIS_KEY, id);
                transaction.publish(redisChannelName, message);
            }
            transaction.exec();
            pool.returnResource(jedis);

我需要在事务内部进行获取,因为有多个发布者可能会发布完全相同的消息。


问题答案:

结束交易之前,您 无法获得获取 结果。

如果使用Redis> 2.6.X,则可以使用Lua脚本通过逻辑来创建函数。参见Redis
Lua

这正是我为保证项目中的并发性所做的事情。

编辑:包括一个更完整的示例

您应该创建类似PUBLISHNX脚本(未经测试)的内容:

local shouldPublish = redis.call('SISMEMBER', KEYS[1], ARGV[1])

if shouldPublish == 0
    redis.call('SADD', KEYS[1], ARGV[1])
    redis.call('PUBLISH', ARGV[2], ARGV[3])
end

然后传递所有必需的参数,即channel,messageId,message,controlKey。

PS。Wei Li是正确的,在并发的情况下,您可以使用WATCH和循环进行重试来实现相同的结果,但是我仍然更喜欢使用Lua脚本。



 类似资料:
  • 问题内容: 当我们在Redis中使用事务时,它基本上流水线化了事务中的所有命令。当EXEC被触发时,所有命令将一起执行,从而始终保持多个命令的原子性。 这与流水线不一样吗? 流水线和事务有何不同?另外,为什么Redis的单线程性质不足以满足要求?为什么我们明确需要流水线/事务? 问题答案: 流水线主要是网络优化。从本质上讲,这意味着客户端可以缓冲一堆命令并将它们一次性发送到服务器。不能保证在事务中

  • 我已经使用jedis将redis集成到我的spring web应用程序中(redis支持AWS弹性缓存)。在单节点上,它可以很好地使用单绝地连接工厂进行读写。 我现在需要将它扩展到一个集群,以便写入主节点并从次节点读取。也就是说,如果一个下降,那么复制将由AWS自动发生,在这种情况下,我将连接的主机名将被更改。 如何读取进入图片的新节点? 我如何从spring容器(我指的是XML文件)连接到它?

  • 主要内容:Java 使用 Redis,1.连接到 redis 服务,2.Redis Java String(字符串),3.Redis Java List(列表),3.Redis Java KeysJava 使用 Redis 开始在 Java 中使用 Redis 前, 我们需要确保已经安装了 redis 服务及 Java redis 驱动,且你的机器上能正常使用 Java。  1.连接到 redis 服务 编译以上 Java 程序,确保驱动包的路径是正确的。 2.Redis Java String

  • 本文向大家介绍通过Maven进行jedis连接redis的实现,包括了通过Maven进行jedis连接redis的实现的使用技巧和注意事项,需要的朋友参考一下 最近项目要用到redis,很多东西忘得差不多了,稍微回顾了利用Java客户端连接redis的过程,这里jedis是连接redis的Java客户端,如果没有Maven,需要手动下载jar包,很麻烦,于是这里使用Maven,记录下连接过程。 1

  • 由于单个redis实例不符合我的要求,我选择了redis cluster。我用三个节点组成集群,并将数据填充到集群中。当我使用JedisCluster从集群获取数据时,它比单个实例花费更多的时间。那么,将绝地与redis星系团连接起来的正确方式是什么呢。我如何利用连接池将绝地与redis集群连接起来?

  • 我们有两个应用程序使用相同的redis缓存集群。其中一个应用程序(比如App1)使用Jedis,另一个应用程序(比如App2)使用Redisson。现在,我们可以假设这两个应用程序都可以将Java对象读写到缓存中,尽管最终可能只有App2(使用Redisson)来完成写操作。 我的问题是,在序列化和反序列化方面,Redisson编写的对象是否可以被Jedis阅读(反之亦然)。 null 更新:Ap