为了避免在我的 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);
我需要在事务中进行获取,因为有多个发布者可能发布完全相同的消息。
你不可能得到你的结果get在您结束交易之前。
如果您使用的是 Redis > 2.6.X,您可以使用 Lua 脚本根据您的逻辑创建一个函数。看Redis 卢阿 http://redis.io/commands/eval
这正是我为保证项目并发性所做的。
编辑:包括更完整的示例
您应该创建类似 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。
附言。 Wei Li 是对的,你可以使用 WATCH 和一个在并发情况下重试的循环来完成相同的结果,但我仍然更喜欢使用 Lua 脚本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)