Redis 不会将错误类型作为事务中的错误返回



应用程序(如果已经询问(。首先,让我展示如何重现我的问题:

  1. 在docker容器中运行Redis
  2. 连接到Redis并执行以下命令:
> SET test 10
  1. 在Go中,运行以下代码:
func main() {
redisClient := getConnection() // Abstracting get connection for simplicity
r, err := redisClient.Do("HSET", "test", "f1", "v1", "f2", "v2")
fmt.Printf("%+v e: %+vn")
}

公平地说,在这个步骤中显示了以下错误(这意味着err != nil(:

WRONGTYPE Operation against a key holding the wrong kind of value e: WRONGTYPE Operation against a key holding the wrong kind of value
  1. 相比之下,执行以下代码:
func main() {
redisClient := getConnection()
redisClient.Send("MULTI")
redisClient.Send("HSET", "test", "f1", "v1", "f2", "v2")
r, err := redisClient.Do("EXEC")
fmt.Printf("%+v e: %+vn")
}

正在打印的行是:

WRONGTYPE Operation against a key holding the wrong kind of value e: <nil>

这对我来说似乎不一致,因为我希望MULTI也返回错误变量中的WRONGTYPE

这是故意的行为还是我遗漏了什么?

Redis事务中的每个命令都有两个结果。一个是将命令添加到事务的结果,另一个是在事务中执行命令的结果。

Do方法返回将命令添加到事务的结果。

Redis EXEC命令返回一个数组,其中每个元素都是在事务中执行命令的结果。检查每个元素以检查单个命令错误:

values, err := redis.Values(redisClient.Do("EXEC"))
if err != nil {
// Handle error
}
if err, ok := values[0].(redis.Error); ok {
// Handle error for command 0.
// Adjust the index to match the actual index of 
// of the HMSET command in the transaction.
}

用于测试事务命令错误的辅助功能可能很有用:

func execValues(reply interface{}, err error) ([]interface{}, error) {
if err != nil {
return nil, err
}
values, ok := reply.([]interface{})
if !ok {
return nil, fmt.Errorf("unexpected type for EXEC reply, got type %T", reply)
}
for _, v := range values {
if err, ok := v.(redis.Error); ok {
return values, err
}
}
return values, nil
}

这样使用:

values, err := execValues(redisClient.Do("EXEC"))
if err != nil {
// Handle error.
}

最新更新