我不太确定如何使用actor来访问数据库。在Akka的文档和书籍中,似乎省略了该主题。
一个解决方案可以是无状态actor中的包装DAO。例如,对于数据库中的每个表(或域对象类型或聚合类型),可以创建一个负责所有CRUD操作的actor。这种变化可以是命令和查询的分离。例如,对于每个数据类型1命令actor(用于并发)和10个查询actor(用于并行)。
另一种方法可能是创建有状态的actor,它们恰好代表数据库中的一行(或域对象实例或聚合实例)。当然,在这种情况下,数据库也可以是事件存储(如akka持久性模块),最终一致地投影到数据库,文档存储或缓存。这与此无关。这种方法实际上是内存缓存的实现,具有所有优点和问题。必须有一种策略来摧毁演员一段时间后不会耗尽记忆。
我将扩展我的DDD问题:
让我们说,我想与Akka演员一起开发一个DDD应用程序。让我们集中在命令部分。在我看来,这应该以这种方式实现:对于每个有界上下文,将有一个端口参与者,例如Spray REST API,用于将消息路由到适当的域服务actor。此服务角色将业务任务与一个或多个域模型聚合进行协调。每个单个聚合都是一个有状态的actor,由服务主体从数据库中恢复(或在新数据上创建)。服务主体将消息发送/路由到所有涉及的聚合角色。接收域模型actor将对其状态+消息执行业务验证,然后将其更改写入数据库,例如,光滑的DAO。将done
发送回服务参与者后,他们就会停止。完成所有聚合演员后,会将done
消息发送回消息的发件人。一个变化可能是不会立即停止有状态域模型参与者,但是在一段时间后,比如3分钟。
这是使用Akka的DDD的有效使用模式吗?
答案 0 :(得分:5)
通常,DB读取操作(cRud)可以由任何actor直接执行。在大多数情况下,无需进行任何特殊处理。只是一个简单的循环来平衡负载。
对于更新操作(CrUD),它们可以拆分为非交叉域/分片。例如,具有单个帐户的所有操作应该优选地由单个演员处理。例如,一个人可能有N个几乎独立的处理参与者和一个路由器,它根据account.hashCode%N将命令路由到其中一个。因此,操作将在参与者之间或多或少地均匀分配,并且每个帐户将按顺序处理。
P.S。 Slick似乎是Akka应用程序的下降数据库库。