如何在使用Jedis时检测watch / exec故障?

时间:2017-06-16 03:24:15

标签: spring jedis spring-data-redis

这是我想要做的一系列操作:

WATCH somekey
MULTI
...
SET somekey somevalue
EXEC

我通过execute(SessionCallback)(伪代码)的RedisTemplate方法执行此操作:

l = template.execute({
  ops.watch("somekey");
  ops.multi()
  ops.opsForValue().set("somekey", "somevalue")
  return ops.exec()
})

我的问题是,当使用jedis时,l不是null而是一个空列表,因此exec失败与exec成功无法区分,因为在multi中没有返回结果的操作。

这似乎可以通过这里的单元测试来证实:https://github.com/spring-projects/spring-data-redis/blob/1.8.4.RELEASE/src/test/java/org/springframework/data/redis/core/RedisTemplateTests.java#L740测试失败的地方已经完成:

if (redisTemplate.getConnectionFactory() instanceof JedisConnectionFactory) {
    assertThat(results, is(empty()));
} else {
    assertNull(results);
}

与下面的testUnwatch测试相比较,它在unwatch之后测试成功的 exec,并且还需要一个空列表(results.isEmpty())。

如何在使用Jedis时区分这两种情况?

1 个答案:

答案 0 :(得分:2)

TL; DR

您无法使用Jedis检测到事务回滚。

说明

Jedis在any case中返回当前可用版本中的List对象(2.8.2,2.9.0)。如果Redis事务已回滚,则此更改是代码清理的一部分,以防止Jedis在null上返回exec(…)

现在,Jedis rolled back the change但是现在大约有一年没有Jedis发布。

如果检测到事务回滚对您的要求至关重要,请尝试different Redis client