提交更改后撤消的设计模式

design pattern for undoing after I have commited the changes

我们可以撤消操作using 命令或备忘录模式。

如果我们使用的是 kafka,那么我们可以以相反的顺序重播流以返回到之前的状态。

比如Googledocs/sheet等也有版本历史

如果是 pcpartpicker,则如下所示:

为了安全起见,我想提交所有内容,但如果需要,我想回到以前的状态。

我知道我们可以禁用自动提交并使用事务控制语言(COMMIT、ROLLBACK、SAVEPOINT)。但我说的是即使在我提交更改后也要撤消。

我该怎么做?

这个问题没有真正通用的答案。这完全取决于您的数据库结构、跨实体事务的跨度、分布式事务、在您可以恢复更改之前允许传递多少 time/transactions 等等。

类似图案的纪念品

Memento Pattern是一种可能的方法,但是由于关系数据库的性质需要修改如下:

  1. 您需要 transaction log table/list 来保存受事务影响的实体和属性(table 和列)的信息及其主键,旧值和新值(交易发生前的值和交易后的值)以及日期时间戳。这与 command (memento) 模式相同。
  2. 接下来您需要一种机制来识别由数据库中的存储过程触发的非显式更新作为事务的结果。这很重要,因为 table 中的更改会触发其他 table 中的更改,而这些 table 没有被 command.
  3. 明确捕获
  4. 回滚机制将需要通过在相同实体上构建后续事务列表来确定事务是否符合回滚条件,并确定此事务是否符合回滚条件,或者某些后续事务需要在回滚此事务之前也要回​​滚。
  5. 如果在较长时间后允许回滚,或者 near-realtime 消耗数据,还应该有一个 list of transaction observers,需要通知进程交易不再有效,因为他们已经读取了新数据并根据它做出了决定。示例是生成累积报告的过程。事务回滚时,回滚会使报表失效,需要重新生成报表。

对于主要用于分布式事务的短期回滚,您可以查看 Microservices Saga Pattern,并将其用作构建解决方案的起点。

历史table年代

另一种方法是保留 incremental updates 或也称为 history tables。该行的每次更新都将插入到历史记录 table 中,并带有新版本。与之前的情况类似,当您尝试回滚已提交的事务时,您需要决定在历史记录中可以追溯到多远。

监管问题

最后,当您处理诸如invoiceinventory等业务数据时,您还需要检查与取消已提交交易相关的规定。例如,在会计系统中,不允许删除数据,而是添加一个带有补偿的新行(例如,从发货列表中删除产品不会删除产品,而是添加一行 -quantity 以取消原始行的影响并同时保持对更改的审计跟踪。