如果其中一个命令不起作用,REDIS-管道不会失败

时间:2019-01-11 19:43:46

标签: redis

我有以下REDIS SET:

127.0.0.1:6379[2]> hgetall available
 1) "00001"
 2) "unassigned"
 3) "00002"
 4) "unassigned"
 5) "00003"
 6) "unassigned"
 7) "00004"
 8) "unassigned"
 9) "00005"
10) "unassigned"
127.0.0.1:6379[2]>

我有以下python代码,该代码使用管道将帐户从可用列表“移动”到保留列表/集:

def reserve_mailboxes(lower, upper):
    try:
        assert(lower is not None)
        assert(upper is not None)
        if DEBUG == True:  print("reserve_mailboxes invoked with lower limit: " + str(lower) + ", upper limit: " + str(upper))
        for number in range(int(lower), int(upper) + 1):
            number = '{0:05d}'.format(number) #zero pad 
            r = redis.Redis(connection_pool=POOL)
            p = r.pipeline()
            p.hmset('reserved', {number:'reserved'})
            p.hdel('available', {number})
            response = p.execute()
            logging.info(response)

            if not response[1] == True:
                if DEBUG == True: logging.info(response)
        return True
    except Exception as e:
        logging.error(e)
        return False

如果您查看我在其中创建和执行管道的代码,则hdel命令实际上存在语法错误。确实应该是:

            p.hdel('available', number)

但是,当我运行此代码时,它将继续并向“保留”列表中添加2个条目...但不会将它们从可用列表中删除。这是我现在的数据:

127.0.0.1:6379[2]> hgetall reserved
1) "00003"
2) "reserved"
3) "00004"
4) "reserved"
127.0.0.1:6379[2]> hgetall available
 1) "00001"
 2) "unassigned"
 3) "00002"
 4) "unassigned"
 5) "00003"
 6) "unassigned"
 7) "00004"
 8) "unassigned"
 9) "00005"
10) "unassigned"

该日志显示两个命令的以下“响应” /结果:

root-INFO-[True,0]

如果hdel有效,则应返回1而不是0。

顺便说一句。当我删除错字时,代码会正确地从一个列表中删除,并添加到另一个列表中。

问题

  1. 我认为,如果其中一条失败,则管道应该还原所有命令。因此,换句话说,由于hdel返回0,是否应该撤消hmset?
  2. 是否有更有效的方法来做到这一点?将记录从一组移到另一组?

2 个答案:

答案 0 :(得分:0)

1)不管您怎么想,管道都只是一种批处理操作而无需等待答复的方式。管道中一个或多个操作的失败*不会**不会阻止回滚其中的其他操作。

2)这些不是集合,而是哈希。您可以查看Lua脚本(请参阅EVAL命令),以通过在Redis服务器中运行逻辑来优化逻辑性能。

答案 1 :(得分:0)

您可以使用 MULTIEXEC 包装流水线命令,使它们成为“原子”。

例如:

MULTI
INCR pipeline_counter
EXPIRE pipeline_counts 3600
EXEC

有关详细信息,请参阅 EXEC 命令的 the doc