StackExchange.Redis: 关于交易的几个问题
StackExchange.Redis: couple of questions about transactions
我有几个关于使用来自 StackExchange.Redis:
的交易的问题
- 是否允许在事务中执行可能针对集群环境中不同节点的命令?比如说,第一个命令的键有
{1}
主题标签,第二个命令的键有 {2}
主题标签。
- 交易的
Execute()
/ExecuteAsync()
return什么时候false
?仅当不满足设定条件时?不设置条件可以returnfalse
吗?
- 如果发生某些网络或内部 Redis 错误,
Execute()
/ExecuteAsync()
会抛出还是只是 return false
?我还应该检查命令的任务(假设命令完全正确并且通常不会抛出)还是它们会被取消?
遗憾的是the doc没有详细解释#2和#3。
- "Redis Cluster implements all the single key commands available in the non-distributed version of Redis. Commands performing complex multi-key operations like Set type unions or intersections are implemented as well as long as the keys all belong to the same node."
https://redis.io/topics/cluster-spec
您不能使用多簇键发送多键操作。
- "交易过程中可能遇到两种命令错误:
命令可能无法排队,因此在调用EXEC之前可能会出错。例如,该命令可能在语法上是错误的(参数数量错误,命令名称错误,...),或者可能存在一些临界条件,如内存不足条件(如果服务器配置为使用 maxmemory 具有内存限制指令)。
调用 EXEC 后命令可能会失败,例如,因为我们对具有错误值的键执行操作(例如对字符串值调用列表操作)。"
https://redis.io/topics/transactions
- 在 .Net 中,当你 运行 一个任务时,如果在其中抛出一个未处理的异常 - 它不会在任务之外冒泡,除非你使用 taskInstance.Wait() - 然后你会得到一个AggregateException 并需要检查 InnerExceptions 以了解实际异常。
我深入研究了 StackExchange.Redis 源代码并试用了驱动程序,以下是我的观察结果:
- 在
ITransaction
个实例上调用 op 方法时没有实际交互发生
- 驱动程序仅在您调用
Execute()
/ExecuteAsync()
时才开始与 Redis 通信
答案似乎如下:
- 正如@royi-mindel 提到的,交易中的所有密钥必须指向同一个插槽。否则你会得到 "Multi-key operations must involve a single slot" 异常。
Execute()
/ExecuteAsync()
returns false
在两种情况下:当事务因为不满足条件而被丢弃时,当驱动程序无法将命令排队时(例如因为服务器 OOM)。所有命令任务都将标记为已取消。另外 Execute()
/ExecuteAsync()
不会 return false
如果其中一个命令在执行过程中失败(例如,由于类型错误操作)。
- 万一出现网络问题,
Execute()
/ExecuteAsync()
会抛出异常,所有命令任务会保持在"waiting for activation"状态。
总而言之,只有在 Execute()
/ExecuteAsync()
returned true
时才应检查命令任务:每个任务都将包含结果或错误(参见 Exception
属性)。
我有几个关于使用来自 StackExchange.Redis:
的交易的问题- 是否允许在事务中执行可能针对集群环境中不同节点的命令?比如说,第一个命令的键有
{1}
主题标签,第二个命令的键有{2}
主题标签。 - 交易的
Execute()
/ExecuteAsync()
return什么时候false
?仅当不满足设定条件时?不设置条件可以returnfalse
吗? - 如果发生某些网络或内部 Redis 错误,
Execute()
/ExecuteAsync()
会抛出还是只是 returnfalse
?我还应该检查命令的任务(假设命令完全正确并且通常不会抛出)还是它们会被取消?
遗憾的是the doc没有详细解释#2和#3。
- "Redis Cluster implements all the single key commands available in the non-distributed version of Redis. Commands performing complex multi-key operations like Set type unions or intersections are implemented as well as long as the keys all belong to the same node." https://redis.io/topics/cluster-spec
您不能使用多簇键发送多键操作。
- "交易过程中可能遇到两种命令错误:
命令可能无法排队,因此在调用EXEC之前可能会出错。例如,该命令可能在语法上是错误的(参数数量错误,命令名称错误,...),或者可能存在一些临界条件,如内存不足条件(如果服务器配置为使用 maxmemory 具有内存限制指令)。
调用 EXEC 后命令可能会失败,例如,因为我们对具有错误值的键执行操作(例如对字符串值调用列表操作)。" https://redis.io/topics/transactions
- 在 .Net 中,当你 运行 一个任务时,如果在其中抛出一个未处理的异常 - 它不会在任务之外冒泡,除非你使用 taskInstance.Wait() - 然后你会得到一个AggregateException 并需要检查 InnerExceptions 以了解实际异常。
我深入研究了 StackExchange.Redis 源代码并试用了驱动程序,以下是我的观察结果:
- 在
ITransaction
个实例上调用 op 方法时没有实际交互发生 - 驱动程序仅在您调用
Execute()
/ExecuteAsync()
时才开始与 Redis 通信
答案似乎如下:
- 正如@royi-mindel 提到的,交易中的所有密钥必须指向同一个插槽。否则你会得到 "Multi-key operations must involve a single slot" 异常。
Execute()
/ExecuteAsync()
returnsfalse
在两种情况下:当事务因为不满足条件而被丢弃时,当驱动程序无法将命令排队时(例如因为服务器 OOM)。所有命令任务都将标记为已取消。另外Execute()
/ExecuteAsync()
不会 returnfalse
如果其中一个命令在执行过程中失败(例如,由于类型错误操作)。- 万一出现网络问题,
Execute()
/ExecuteAsync()
会抛出异常,所有命令任务会保持在"waiting for activation"状态。
总而言之,只有在 Execute()
/ExecuteAsync()
returned true
时才应检查命令任务:每个任务都将包含结果或错误(参见 Exception
属性)。