如何在Redis

时间:2016-09-20 04:50:09

标签: java database transactions redis

我的程序需要将数据添加到Redis中的两个列表作为事务。两个列表中的数据应保持一致。如果存在异常或系统故障,因此程序仅将数据添加到一个列表,则系统应该能够恢复和回滚。但是基于Redis doc,它不支持回滚。我该如何实现呢?我使用的语言是Java。

2 个答案:

答案 0 :(得分:2)

如果您需要事务回滚,我建议使用Redis以外的其他东西。 Redis事务与其他数据存储不同。甚至Multi / Exec也无法满足您的需求 - 首先是因为没有回滚。如果你想要回滚,你必须下拉两个列表,以便你可以恢复 - 并希望在我们的错误条件和“回滚”之间没有其他客户端也修改了任何一个列表。以理智和可靠的方式做到这一点并非易事,也不简单。它也可能不是一个很好的问题,因为它会非常广泛,而不是特定的Redis。

现在,为什么EXEC没有做出人们的想法。在您建议的场景中,MULTI / EXEC 处理以下情况:

  1. 您设置了WATCH以确保没有发生其他更改
  2. 您的客户在发出EXEC之前已经死亡
  3. Redis内存不足
  4. 完全有可能因发出EXEC命令而出错。当您发出EXEC时,Redis将在队列中执行所有命令并返回错误列表。它不会提供add-to-list-1工作和add-to-list-2失败的情况。你仍然会让你的两个列表不同步。当您在发出MULTI后发出LPUSH时,除非您:

    ,否则您将始终返回OK
    • a)之前添加了一个手表,该列表中的内容已更改或
    • b)Redis返回OOM条件以响应排队的推送命令

    DISCARD不像有些人想象的那样有效。 DISCARD使用而不是 EXEC,而不是作为回滚机制。一旦您发出EXEC,您的交易就完成了。 Redis根本没有任何回滚机制 - 这不是Redis的交易所涉及的。

    理解Redis调用事务的关键是要意识到它们本质上是客户端连接级别的命令队列。它们不是数据库状态机。

答案 1 :(得分:0)

Redis交易不同。它保证了两件事。

  1. 执行所有命令或不执行任何命令
  2. 顺序和不间断的命令
  3. 话虽如此,如果您可以控制代码并知道何时会发生系统故障(某种程度上捕获异常),您就可以通过这种方式实现您的需求。

    1. MULTI - >开始交易
    2. LPUSH queue1 1 - >推进队列1
    3. LPUSH queue2 1 - >推进队列2
    4. EXEC / DISCARD
    5. 在第4步中,如果没有错误,请执行EXEC,如果遇到错误或异常,并且想要回滚,请执行DISCARD。

      希望它有意义。

相关问题