Actor 模型的最大优势之一是消除了锁定(Actor 独立且连续地操作)。这是否意味着我们在参与者系统中根本不能拥有任何共享/全局状态(因为访问/更新会带来锁)?
在更实际的情况下,在这样的系统中,来自多个参与者的实体(例如 DB)的更新会发生什么?
Actor 模型的最大优势之一是消除了锁定(Actor 独立且连续地操作)。这是否意味着我们在参与者系统中根本不能拥有任何共享/全局状态(因为访问/更新会带来锁)?
在更实际的情况下,在这样的系统中,来自多个参与者的实体(例如 DB)的更新会发生什么?
Actor 模型旨在以另一种方式解决任何可变共享状态的问题 - Actor 应该封装它。因此,如果您需要在参与者之间共享某些内容 - 这应该是具有此状态和协议的参与者来使用它。如果您想从不同的参与者更新数据库 - 提取负责此操作的参与者,并为其他参与者提供 API 或协议以更新数据库。或者让多个参与者处理数据库更新并在它们之间路由消息(请参阅更多详细信息:https ://doc.akka.io/docs/akka/current/typed/routers.html )
一般方法 - 考虑共享状态,作为参与者之间共享的参与者(通过ActorRef
)和状态 API 作为该参与者的消息。
通常,在参与者系统中拥有共享/全局状态不是首选方式。与演员合作时的一个非常核心的想法是不共享任何可变状态,相反,可变状态被封装在演员内部,如文档中所指出的那样
不要在actor之间传递可变对象。为了确保这一点,更喜欢不可变消息。如果通过将actor的可变状态暴露给外部而破坏了actor的封装,那么您将回到具有所有缺点的普通Java并发领域。
Actor 是行为和状态的容器,接受这意味着不要在消息中定期发送行为(使用 Scala 闭包可能很诱人)。风险之一是意外地在 Actor 之间共享可变状态,不幸的是,这种违反 Actor 模型的行为破坏了使在 Actor 中编程成为一种很好的体验的所有属性。
此外,如果一个 Actor 需要了解另一个 Actor 的状态,它会使用不可变消息来询问它并获得不可变的回复。Akka Actor 的一个关键特性是它们能够以线程安全的方式管理状态和通过具有共享和可变状态,我们将违反此属性
通常 DB 读取操作 (CRUD) 可以由任何参与者直接执行。执行此操作。让一个演员对此负责,并从其他演员那里使用它。
让我知道它是否有帮助!