从 Rails CRUD 迁移到事件溯源


您是否想知道如何将模型从 CRUD 模型实际切换到 EventSourcing?有件事你应该考虑。必须为现有数据发布的初始事件。也称为迁移事件。

在某个时刻,人们将达到能够从旧模型切换到新模型的时刻。精心设计、事件来源的聚合。

但随后问题出现了……如何将数据从旧模型迁移到新聚合?您应该如何通过迁移事件为聚合播种?

迁移事件
说到迁移事件,基本上至少有两种选择。

  • 第一种选择是从 "启动starts "聚合体生命周期的事件开始。如果您的聚合是一个 BankAccount,它通过 open 方法启动,并产生 BankAccountOpened 事件,那么您就可以通过调用该方法产生该事件来迁移您的遗留模型。
  • 第二种方法有点不同。你可以引入一个仅用于迁移的新事件,而不是从启动聚合体生命周期的常规事件开始。用于初始期初余额。对于 BankAccount,迁移事件可以命名为 LegacyBankAccountImported。

你可能会说第二种是额外的、不必要的工作。这种方法有一个巨大的进步。将来,如果要分析数据流,就可以将已迁移的聚合与迁移后创建的聚合区分开来。从调试的角度来看,这是非常有用的信息。我通常更喜欢这种方式。

让我们处理初始事件:

def stream_name(aggregate_id)
  "BankAccount$#{aggregate_id}"
end

legacy_bank_accounts = BankAccount.unscoped

repository = AggregateRoot::Repository.new

legacy_bank_accounts.each do |legacy_bank_account|
  aggregate_id = legacy_bank_account.uniq_id
  ApplicationRecord.with_advisory_lock(legacy_bank_account.uniq_id) do
    repository.with_aggregate(Banking::BankAccount.new(aggregate_id), stream_name(aggregate_id)) do |bank_account|
        bank_account.import_deleted(legacy_bank_account.balance, legacy_bank_account.balance_date)
      end
    end
  end
end

可以看到,脚本使用旧模型加载数据。然后遍历这些数据并调用其中一个导入方法(取决于传统模型的状态),产生聚合的迁移事件。本例中的事件是 LegacyBankAccountImported 或 ClosedLegacyBankAccountImported。

就是这样。现在就可以切换到新模型了