我正在尝试Akka Persistence,并遇到了有关同时访问同一持久性actor的问题。 这是关于确保每个id最多运行一个实例。
我有一个名为CustomerActor的简单持久性actor,它具有一些简单的实验室目的功能,为便于说明,我们将其称为属性A,其状态通过命令进行更改并使用事件源持久化。 该应用程序接受并发输入,这意味着如果我在代码中像这样访问CustomerActor:
val customerActor = system.actorOf(Props(classOf[CustomerActor], "SE",id), CustomerActor.name("SE", id))
其中代码可以并发执行(val customerActor是本地范围的值,因此对于两个并发执行的调用,将有两个CustomerActor实例,每个实例都是从持久性存储中派生的。实际上,直到发现之前,我才意识到这一点在同一实体上执行高度并发计算的意外结果。
现在,如果我愿意
val customerActorFuture = system.actorSelection("user/customeractor.SE.{$id}").resolveOne()
val customerActor = Await.result(customerActorFuture, timeout.duration)
如果不发生争用情况并且查找CustomerActor的时间足够短,我将使用同一实例,并且一切都很好。 我的问题是:我是否缺少执行此操作的最新标准?我需要确保我只使用一个持久性actor的实例,这是我们要为此使用actor的核心功能之一。因此,我实际上期望system.actorOf具有“仅创建一个没有实例的新实例”的语义,如果我使用actorSelection(两个线程“同时”发现没有actor并因此在每个。
感谢您对此问题做出了明确的答复。
编辑:
我犯了一个愚蠢的错误,破坏了应用程序的行为:在使用system.actorOf
获得的两个actor引用中,我忘记在第二个引用中使用name参数。
当然这是行不通的,因为那时名称将由Akka生成,并且有两个具有相同持久性ID的CustomerActor实例。 现在,我更正了在两个实例中都使用name参数的代码,然后得到了预期的行为:仅在使用指定名称不存在actor的情况下创建actor。
如果将来对其他人有帮助的话,我将保留这个问题。