我们可以在基于参与者的系统中拥有全局状态吗?

Can we have global state in actor-based systems?

actor 模型的最大优点之一是去除了锁定(actor 独立和串行操作)。这是否意味着我们在 actor 系统中根本不能有任何 shared/global 状态(因为 accessing/updating 会带来锁)?

更实际地说,在这样一个系统中,多个参与者对实体(例如数据库)的更新会发生什么?

Actor 模型旨在以另一种方式解决任何可变共享状态的问题 - Actor 应该封装它。因此,如果您需要在 actor 之间共享某些东西——这应该是一个具有这种状态和协议的 actor 来使用它。如果您想从不同的演员更新数据库 - 提取负责此的演员,并为其他演员提供 API 或协议以更新数据库。或者让几个 actor 来处理数据库更新并在它们之间路由消息(请参阅更多详细信息:https://doc.akka.io/docs/akka/current/typed/routers.html

一般方法 - 考虑共享状态,作为参与者之间共享的参与者(通过 ActorRef)和状态 API 作为此参与者的消息。

通常,在 actor 系统中拥有 shared/global 状态不是首选方式。使用 actor 时的一个非常核心的想法是不共享任何可变状态,相反,可变状态被封装在 actors 内部,如 documanetation

中所指出的

Do not pass mutable objects between actors. In order to ensure that, prefer immutable messages. If the encapsulation of actors is broken by exposing their mutable state to the outside, you are back in normal Java concurrency land with all the drawbacks.

Actors are made to be containers for behavior and state, embracing this means to not routinely send behavior within messages (which may be tempting using Scala closures). One of the risks is to accidentally share mutable state between actors, and this violation of the actor model unfortunately breaks all the properties which make programming in actors such a nice experience.

此外,如果一个 actor 需要了解另一个 actor 的状态,它将使用不可变消息请求它并获得 Akka actor 的关键特征的不可变 reply.One 及其管理状态的能力以线程安全的方式并通过共享和可变状态,我们将违反此 属性

通常任何数据库读取操作(CRUD)都可以直接执行 actor.To 执行此操作。让一个演员对此负责,并从其他演员那里使用它。

如果有帮助请告诉我!!