StackExchange.Redis:关于交易的几个问题

时间:2018-02-09 17:34:13

标签: c# .net redis stackexchange.redis redis-cluster

我有几个关于使用StackExchange.Redis的交易的问题:

  1. 是否允许在事务中执行可能针对集群环境中不同节点的命令?比如说,第一个命令的密钥有{1}个主题标签,第二个命令的密钥有{2}个主题标签。
  2. 交易的Execute() / ExecuteAsync()何时返回false?只有在没有达到设定的条件时?如果没有设置条件,它可以返回false吗?
  3. 如果发生某些网络或内部Redis错误,Execute() / ExecuteAsync()会抛出或只返回false吗?我是否还要检查命令的任务(假设命令完全正确并且通常不会抛出)或者它们将被取消?
  4. 不幸的是the doc没有详细解释#2和#3。

2 个答案:

答案 0 :(得分:5)

我已经挖掘了一下StackExchange.Redis的源代码并与驱动程序一起玩,以下是我的观察:

  • ITransaction实例
  • 上调用op方法时,没有发生实际的交互
  • 只有在您致电Execute() / ExecuteAsync()
  • 时,才会开始与Redis通话

答案似乎如下:

  1. 正如@ royi-mindel所提到的,交易中的所有密钥都必须以同一个插槽为目标。否则你得到"多键操作必须涉及一个插槽"异常。
  2. Execute() / ExecuteAsync()在两种情况下返回false:由于条件未满足而导致事务被丢弃,以及驱动程序无法对命令进行排队(例如,由于服务器OOM) 。所有命令任务都将标记为已取消。如果其中一个命令在执行期间失败(例如,由于错误的类型操作),Execute() / ExecuteAsync() 也不会返回false
  3. 如果发生某些网络问题,Execute() / ExecuteAsync()将抛出异常并且所有命令任务将保持在"等待激活"状态。
  4. 总而言之,只有Execute() / ExecuteAsync()返回true时才会检查命令任务:每个任务都会包含结果或错误(请参阅Exception属性)。

答案 1 :(得分:1)

  1. “Redis Cluster实现了Redis的非分布式版本中可用的所有单键命令。执行复杂的多键操作(如Set类型联合或交叉)的命令也被实现,只要这些键都属于同一节点“。 https://redis.io/topics/cluster-spec
  2. 您无法使用多群集密钥发送多键操作。

    1. “在事务期间,可能会遇到两种命令错误:
    2. 命令可能无法排队,因此在调用EXEC之前可能会出错。例如,命令可能在语法错误(错误的参数数量,错误的命令名称,......),或者可能存在某些严重情况,如内存不足情况(如果服务器配置为使用maxmemory具有内存限制指令)。

      在调用EXEC之后,命令可能会失败,例如,因为我们对具有错误值的键执行了操作(比如对字符串值调用列表操作)。 https://redis.io/topics/transactions

      1. 在运行任务时在.Net中,如果在其中抛出未处理的异常 - 除非您使用taskInstance.Wait(),否则它将不会在任务之外冒泡 - 然后您将获得AggregateException并需要检查InnerExceptions以查找实际例外。