【发布时间】:2019-03-04 16:58:36
【问题描述】:
在Axon Giftcard demo 中,有一个GiftCard 类被注释为@Aggregate:
@Aggregate
@Profile("command")
public class GiftCard {
private final static Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@AggregateIdentifier
private String id;
private int remainingValue;
@CommandHandler
public GiftCard(IssueCmd cmd) {
log.debug("handling {}", cmd);
if(cmd.getAmount() <= 0) throw new IllegalArgumentException("amount <= 0");
apply(new IssuedEvt(cmd.getId(), cmd.getAmount(), cmd.getCurrency()));
}
@CommandHandler
public void handle(RedeemCmd cmd) {
log.debug("handling {}", cmd);
if(cmd.getAmount() <= 0) throw new IllegalArgumentException("amount <= 0");
if(cmd.getAmount() > remainingValue) throw new IllegalStateException("amount > remaining value");
apply(new RedeemedEvt(id, cmd.getAmount()));
}
...
@EventSourcingHandler
public void on(IssuedEvt evt) {
log.debug("applying {}", evt);
id = evt.getId();
remainingValue = evt.getAmount();
currency = evt.getCurrency();
log.debug("new remaining value: {}", remainingValue);
log.debug("new currency: {}", currency);
}
@EventSourcingHandler
public void on(RedeemedEvt evt) {
log.debug("applying {}", evt);
remainingValue -= evt.getAmount();
log.debug("new remaining value: {}", remainingValue);
}
...
命令和事件类在 Kotlin 代码中定义:
data class IssueCmd(@TargetAggregateIdentifier val id: String, val amount: Int)
data class IssuedEvt(val id: String, val amount: Int)
data class RedeemCmd(@TargetAggregateIdentifier val id: String, val amount: Int)
data class RedeemedEvt(val id: String, val amount: Int)
假设将以下两条命令放在命令总线上:
Command # Command Class id amount
--------- ------------- ------- -------------
1 IssueCmd QP34 123.45
2 RedeemCmd QP34 38.10
在处理第一个命令时,IssueCmd 的 CommandHandler (CH) 将在事件总线上放置一个 IssuedEvt 对象。事件将由 IssuedEvt 的 EventSourcingHandler (ESH) 处理。然后我们将有一个GiftCard 的实例,其中id 设置为“QP34”,remainingValue 设置为123.45。
在处理第二个命令时,RedeemCmd 的 CH 将在事件总线上放置一个 RedeemedEvt 对象。该事件将由 RedeeemedEvt 的 ESH 处理。然后我们将有一个GiftCard 的实例,其中id 设置为“QP34”,remainingValue 设置为85.35。
问题:每个事件都由其指定的 ESH 处理后,生成的对象实例如何以及在何处持续存在?
以前,我听到的答案是:确实没有。所有持续存在的都是事件对象,它们保存在 Axon 的事件存储中。当需要一个对象的当前状态时,Axon 告诉命令模型启动一个GiftCard 类的实例,并将事件从最早到最晚应用于它。这就是事件溯源的定义。
但是,当事件溯源时,在处理 IssuedEvt 之后,remainingValue 中的 123.45 必须在某处持久化,以便 RedeemedEvt 的 ESH 具有正确的值为它的减法运算。
在调用 ESH 之间对象状态如何以及在何处保持?
【问题讨论】:
标签: java kotlin persistence axon