当前位置: 首页 > 知识库问答 >
问题:

如何在应用程序启动前重播数据库中的事件?

淳于博文
2023-03-14
    null

(该事件创建一个新的Webshop,并将其余额设置为100)。该事件将持久化到我的数据库中。当我查询当前webshop余额时,我可以返回当前余额为100。(事件和查询的代码如下所示)

但是,如果我重新启动应用程序,并试图再次查询当前余额,以前的事件不会被重播,因此我无法获得当前余额(重新启动后,事件仍然存在于数据库中,因此我认为这只是框架没有检索所有以前的事件的问题)。

我目前使用缺省配置,Axon 4.0.3 for Spring和将事件存储到本地文件的H2数据库(我知道H2不是最好的选择,但这只是为了一个小的概念验证,显示事件源和CQRS,所以不需要大的和可伸缩的)。

@Service
@NoArgsConstructor
public class WebshopsEventHandler {

    private final Map<String, Webshop> webshops = new HashMap<>();

    // ... some other unrelated code

    @EventSourcingHandler
    public void on(ShopCreatedEvent shopCreatedEvent) {
        this.webshops.put(
                shopCreatedEvent.getId(),
                new Webshop(
                        shopCreatedEvent.getId(),
                        shopCreatedEvent.getName(),
                        shopCreatedEvent.getBalance() // Balance is 100 as default
                )
        );
    }

    // ... some more unrelated code

    @QueryHandler
    protected Optional handle(GetCurrentBalanceQuery getCurrentBalanceQuery) {
        System.out.println("Balance query");
        if (webshops.containsKey(getCurrentBalanceQuery.getShopId())) {
            return Optional.of(webshops.get(getCurrentBalanceQuery.getShopId()).getBalance());
        } else {
            return Optional.empty();
        }
    }
}

如何配置Axon 4以在重新启动后检索以前的所有事件?

共有1个答案

令狐建修
2023-03-14

我想在这种情况下我能帮你。让我首先给出一些背景知识,说明为什么每次启动时没有填充“查询模型存储”,即私有最终映射 webshop>

@EventHandler注释函数提供事件的技术机制称为事件处理器。在4.0版本之外,Axon Framework默认为TrackingEventProcessor

正如名称所示,TrackingEventProcessor跟踪自己的事件处理。它通过存储trackingtoken-在您的设置中,这意味着它将存储在H2数据库文件中。此TrackingToken存储(除其他外)给定TrackingEventProcessor处理的最后一个事件。

您可以通过在TrackingEventProcessor上启动重播来实现这一点,这里将对此进行详细说明。然而,由于您只是展示它是如何工作的,而不是创建一个持久的系统,所以我建议一些更务实的方法。

如果将tokenstore(负责存储令牌的组件)调整为inmemorytokenstore,那么您的应用程序将不会在应用程序关闭之间跟踪事件处理器的进度。为此,您可以在配置文件或@springbootapplication注释类中执行以下操作(假设您使用的是Spring Boot):

@Autowired
public void configureInMemoryTokenStore(EventProcessingConfigurer configurer) {
    configurer.registerTokenStore(configuration -> new InMemoryTokenStore());
}

希望这能有所帮助!

 类似资料: