将应用程序中的数据恢复(回滚)到指定状态(日期)的最佳方法是什么?

时间:2010-05-19 15:34:54

标签: java design-patterns database-design

示例将右上角设置,下面的示例捕获实体的各种状态,需要还原(回滚)。

州1 - 于2010年3月1日录制

Column1 Column2
Data1    0.56

国家2 - 于2010年3月2日录制

Column1 Column2
Data1    0.57

状态3 - 于2010年3月3日录制

Column1 Column2
Data1    0.58

用户注意到state3不是他打算进入的状态,决定恢复到state2。

我可以想到的一种方法是在不修改实体的情况下通过“审核”所有插入/更新,如下所示,回滚信息在实体更新/修改之前捕获数据,以便它可以是在需要还原时按顺序应用。请注意,更改实体的架构不是一种选择。

回滚 - R1记录于2010年3月1日

Column1 Column2
Data1    0.56

回滚 - 在2010年3月2日录制的R2

Column1 Column2
Data1    0.56

回滚 - R3于2010年3月3日录制

Column1 Column2
Data1    0.57

因此,要进入state2,我们将从回滚信息R1开始,将R2应用到它上面。

有没有更好的方法来实现这一目标?

感谢您的时间。

5 个答案:

答案 0 :(得分:1)

对于架构中的每个表,在另一个架构中创建一个新的审核表,其中包含两个附加列:validFromvalidTo

插入/更新行时,需要在审计表中进行两处更改:

update auditTable set validTo = sysdate where validTo is null
insert auditTable ...copy-of-all-columns..., validFrom = sysdate

(如果删除原始表中的行,则不插入)。

如果您需要返回某个状态,可以选择审核表中具有相同主键(PK)的行,该行位于[ validFrom, validTo )validTo is none的时间范围内只需将行复制到原始表中即可。

接下来,您必须删除原始表中当时在审计表中不存在的所有行。

答案 1 :(得分:1)

只需将当前值/状态更新为您想要的值/状态。

通常,这是您唯一的选择。这样做的原因是你通常不能预测你的那种“回滚”可能对数据库的一致性产生的影响。

具有状态S3的实体E1可能是某个其他实体E2被允许具有某些状态Sx的先决条件,这可能与具有状态S1的E1“不兼容”。

允许E1回滚到以前的状态S1而不对E2做任何事情,会导致数据库变得不一致。

答案 2 :(得分:0)

您可以使用字段或单独的引用表来指示“当前”实体状态,而不是“应用”更新。这样,回滚将是移动标志或将引用更改为审计表中的另一个实体的问题。

答案 3 :(得分:0)

这可能不适合数据库驱动的应用程序,但可能有用的一般设计模式是Memento模式:

http://en.wikipedia.org/wiki/Memento_pattern

答案 4 :(得分:0)

你需要的是像Linux的FS ext3这样的机制 - 期刊。 (我不确定,但它可能是solaris文件系统的ZFS模型,但这不重要)

他们的想法是为每个文件存储日志(理解它为对象/条目/ ...),并且每次发生的变化都会创建另一个只存储更改的入口点,因此您不会有复制。您可以轻松快速地回滚 - 您只需要向后回滚到6个版本,文件系统会执行以下操作:

删除最后6个版本,并将currentVersion-6标记为最新版本,您可以继续使用。

难以实现的是让商店积分快速计算并进行优化 - 我不知道您日记中新条目计算的好算法,但应该在互联网上。

你可以制作适合DB的东西。 你是怎么找到它的?我已经在Solaris上使用ZFS看到了这个并且它的工作速度非常快,而且这个文件系统去年被授予(或者是2008年......?),因为它具有非常高的质量。