我正在阅读《会计模式》,并对在CQRS中实现它感到非常好奇。
我认为AccountingTransaction是一个聚合根,因为它保护着不变量:
没有资金泄漏,应该从一个账户转移到另一个账户。
public class AccountingTransaction {
private String sequence;
private AccountId from;
private AccountId to;
private MonetaryAmount quantity;
private DateTime whenCharged;
public AccountingTransaction(...) {
raise(new AccountingEntryBookedEvent(sequence, from, quantity.negate(),...);
raise(new AccountingEntryBookedEvent(sequence, to, quantity,...);
}
}
当 AccountingTransaction 被添加到其存储库时,它会发布多个 AccountingEntryBookedEvent。这些事件将用于在查询端更新相应账户的余额。每个数据库事务更新一个聚合根,最终一致性,目前为止看起来不错。
但是,如果一些账户应用了转移约束,例如不能转移比当前余额更多的数量,怎么办?我可以使用查询端获取账户余额,但我担心查询端的数据已经陈旧。
public class TransferApplication {
public void transfer(...) {
AccountReadModel from = accountQuery.findBy(fromId);
AccountReadModel to = accountQuery.findBy(toId);
if (from.balance() > quantity) {
//create txn
}
}
}
我应该在命令端对账户进行建模吗?每次数据库事务(从/到帐户和帐户交易)中至少要更新三个聚合根。
public class TransferApplication {
public void transfer(...) {
Account from = accountRepository.findBy(fromId);
Account to = accountRepository.findBy(toId);
Transaction txn = new Transaction(from, to, quantity);
//unit or work locks and updates all three aggregates
}
}
public class AccountingTransaction {
public AccountingTransaction(...) {
if (from.permit(quantity) {
from.debit(quantity);
to.credit(quantity);
raise(new TransactionCreatedEvent(sequence, from, to, quantity,...);
}
}
}