有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Redis中实现事务回滚

我的程序需要将数据作为事务添加到Redis中的两个列表中。两个列表中的数据应一致。若出现异常或系统故障,程序只向一个列表中添加了数据,那个么系统应该能够恢复和回滚。但是基于Redis文档,它不支持回滚。我如何实现这一点?我使用的语言是Java


共 (2) 个答案

  1. # 1 楼答案

    如果需要事务回滚,我建议使用Redis以外的其他工具。Redis事务与其他数据存储不同。即使Multi/Exec也不能满足您的需求——首先,因为没有回滚。如果你想回滚,你必须把这两个列表都拉下来,这样你就可以恢复——希望在我们的错误情况和“回滚”之间,没有其他客户端也修改了这两个列表。以理智和可靠的方式做这件事不是小事,也不简单。这也可能不是一个好问题,因为这将是一个非常广泛的问题,而不是特定于Redis的问题

    至于为什么EXEC不做人们可能认为的事情。在您提出的方案中,MULTI/EXEC处理以下情况:

    1. 你设置了手表以确保没有其他变化发生
    2. 你的客户在发出EXEC之前就死了
    3. Redis内存不足

    发出EXEC命令完全可能导致错误。当您发出EXEC时,Redis将执行队列中的所有命令,并返回错误列表。它不会提供add-to-list-1工作和add-to-list-2失败的情况。你的两个列表仍然会不同步。当你发出时,比如在发出MULTI之后发出一个LPUSH,你总会得到一个OK,除非你:

    • a) 之前添加了一块手表,列表中的某些内容发生了变化或
    • b) Redis返回OOM条件以响应排队的push命令

    丢弃并不像有些人所想的那样有效。DISCARD使用代替EXEC,而不是作为回滚机制。一旦你发出EXEC,你的交易就完成了。Redis根本没有任何回滚机制——这不是Redis事务的目的

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

  2. # 2 楼答案

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

    1. 全部或全部不执行命令
    2. 连续和不间断的命令

    话虽如此,如果你能控制你的代码,并且知道什么时候会发生系统故障(某种程度上捕捉到异常),你就可以通过这种方式实现你的需求

    1. 多功能>;开始交易
    2. LPUSH队列1->;排队1
    3. LPUSH队列2 1->;排队2
    4. 执行/放弃

    在第4步中,如果没有错误,如果遇到错误或异常,并希望回滚,则执行EXEC。执行放弃

    希望它有意义