【发布时间】:2021-02-27 15:54:24
【问题描述】:
我们的用户会经历几个工作流程步骤 - 他们走得越远,我们创建的对象就越多。我们还允许用户返回步骤#1 并更改现有对象之一。这可能会导致不一致,因此我们必须在第 2 步更新/删除一些对象。我看到 2 个选项:
-
立即从第 2 步更新/删除对象。这导致:
- 应该是实体字段的简单 PATCH 的操作变得复杂。它是多个工作流之间的共享对象 - 因此我们必须添加 if 语句并根据工作流执行不同的操作。
- 循环依赖。 Step#1 上的操作必须了解 Step#2 上的对象/操作。
- 对于步骤#1 中的每个请求,我们必须为步骤#2 加载数据,以确定步骤#2 是否真的需要更新。这会减慢第 1 步的操作。因此,要更改 DB 中的 1 条记录,我们必须为第 2 步加载数百(甚至数千)条记录。
- Step#1 上的许多操作可能需要在 Step#2 处修复状态。因此,我们必须确保我们不会忘记今天和未来的任何事情。
-
懒惰地修复第 2 步 - 当用户去那里时(我们当前的方法)。步骤#2 将识别对象不一致并修复它们。这导致我们只需要关心 1 个地方,但是:
- 直到用户打开步骤#2 - DB 将包含不一致的对象。到目前为止,这还没有导致任何问题。但我可以想象它可能会使未来的 SQL 迁移变得复杂。
- 我们根据 GET 请求更新数据库状态。这似乎没什么大不了的,因为 GET 无论如何都保持幂等性。但还是觉得别扭。
有人知道更好的方法吗?或者可能对这两个进行改进?
更新
我还没有找到完美的解决方案,但最终我们实现了 #1 的改进版本。当在 Step#1 上更新状态时,我们还设置了一个标志“需要重建 Step#2”,当 UI 打开 Step#2 时,它首先检查此标志并发出 PUT 以重建状态,然后才获取 Step#2。
这仍然意味着数据库状态在一段时间内不一致。但至少我们可以从 DB 中的标志中确定这一点。如果需要 - 我们可以考虑这个标志来编写迁移。这也允许(如果将来需要)创建一个异步作业来修复状态。
【问题讨论】:
-
第三种选择:您可以在一夜之间运行批处理作业,以协调任何已修改工作流的状态。然后你在数据库中实现了一种最终的一致性。
-
@jaco0646,好吧,用户可以立即进入步骤#2,所以即使我们继续工作,我们也需要能够在下一次 GET 时更正状态。虽然我们可以结合这些方法并确保即使用户离开家而没有进入下一步,实验也处于一致状态..
标签: oop design-patterns architecture