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