2016-09-20 85 views
0

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

回答

0

Redis事务是不同的。它保证两件事。

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

说了这么多,如果你在你的代码的控制,并知道当系统出现故障会发生(某种捕捉异常)你可以通过这种方式达到你的要求。

  1. MULTI - >启动事务
  2. LPUSH队列1 1 - >推入队列1
  3. LPUSH队列2 1 - >推入队列2
  4. EXEC /抛弃

在第四如果没有错误,则执行EXEC,如果遇到错误或异常,并且想要回滚,执行DISCARD。

希望它是有道理的。

2

如果您需要事务回滚,我推荐使用Redis之外的其他方法。 Redis事务与其他数据存储不同。即使Multi/Exec也不能满足你的需要 - 首先是因为没有回滚。如果你想回滚你将不得不拉下这两个列表,所以你可以恢复 - 并希望在我们的错误条件和“回滚”之间没有其他客户端也修改任何一个列表。以一种理智而可靠的方式来做这件事不是微不足道的,也不是简单的。这对于SO来说也可能不是一个好问题,因为它将非常广泛,而不是Redis特有的。

现在至于为什么EXEC不会做任何人可能会想到的事情。在你提出的方案MULTI/EXEC 只有处理的情况:

  1. 您设置的手表,以确保没有其他变化发生
  2. 您的客户端发出EXEC
  3. 前去世
  4. Redis的内存不足

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

  • 一)先前添加在该列表中改变了手表和一些或
  • B)的Redis返回OOM条件以响应排队的推送命令

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

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