【问题标题】:How to achieve MVCC in actor modelActor模型中如何实现MVCC
【发布时间】:2017-07-04 13:50:30
【问题描述】:

假设我已将我的 Employee 实体表示为演员。我有 2 个服务也被建模为演员。它们都通过向其发送消息来操纵它收到的 Employee Actor 的状态。现在假设这两个服务都在处理同一个actor。现在,员工参与者完全有可能按照以下顺序从两个服务 A 和 B 接收状态更改消息

Employee <- |a1|a2|a3|b1|b2|b3|

这很好。但有时它不是

Employee <- |a1|b1|a2|b2|a3|b3|

也许a2 依赖于a1 更改的状态,但b1 更改了它

类似于数据库,我们有事务,因此我们可以在整个事务生命周期中使用数据的单个快照/版本。

在命令式模型中,我们将锁定整个员工对象并更新其状态,类似于数据库的操作方式。

那么,演员是否有可能接收将作为一个原子系列消息处理的批量消息?还是我对数据本身的建模存在缺陷?

【问题讨论】:

    标签: concurrency actor


    【解决方案1】:

    由于我不知道 a1-a3 和 b1-b3 实际代表什么,我只能假设正确回答了这个问题。对我来说,您的消息似乎太细了。例如,也许 a1-a3 试图在每条消息中只设置一个数据属性。 b1-b3 可能也是如此。

    但是,您的信息应该关注的是导致员工的行为,而不是设置个人属性。因此,正如您自己建议的那样,将您的消息设计为行为,其中 a1-a3 将折叠为单个操作请求。这通常称为命令模式,您可以在其中命令/告诉对象/演员做某事。这样做会导致每条消息的事务边界正确。

    请注意,上面我说的是“对象/演员”。您可以/应该在您的对象设计中使用相同的方法,而不仅仅是针对演员。考虑揭示意图的接口并告诉您的域模型您希望它为您做什么,而不是将域对象/参与者视为愚蠢的数据持有者。

    这就是我对你的问题的看法。 HTH。

    沃恩

    【讨论】:

    • 这就是我最终的结果。无论我会在事务块中写入什么更改,我都会使用一条消息创建一条消息来完全执行该事务!谢谢!
    【解决方案2】:

    他们都操纵它收到的 Employee 演员的状态 通过向它发送消息。

    嗯。根据定义,Actor 不与任何其他 Actor 共享其状态或操作。任何状态操作都是在 one 消息处理的边界内进行的。从这个意义上说,Actor 代表一个聚合。消息通常是 事件/命令,并且具有范围和通用语言的一部分。 在考虑 Actor 时,DDD 推理有很大帮助。

    我的两分钱

    谢尔盖

    【讨论】:

    • “突变/事务行为必须限制在单个消息内”。很高兴这是我们实际需要在 actor 模型中应用的那种模式
    • 因此,我真的很喜欢 DDD 和 ActorModel 范式的融合方式,让 EventSourcing 和 CQRS 成为自然的选择,让最终一致性处于适当的位置。
    • @SergiyChernets 我记得您在 Microsoft Channel9 节目中的演讲 - DDD 和 CQRS on Service Fabric。关于理论部分和图表的讨论很棒,但是(演示)实现有点出乎我的意料。过于笨重和大量的支持代码,分散了对实际领域的关注。我认为,问题在于 C# 语法本身。我用 Erlang 实现了类似的概念,这非常优雅。您是否尝试过 F#?
    • @ajukraine 我应该指出三件事。首先,我们演示的代码不是真实的。明显地。 :) 该代码是在 1 小时内创建的。展示 DDD 和 Actor Model 之间的方法和概念联系。其次,它是 Service Fabric 的 Virtual Actors 之上的抽象。第三,我们使用可用的技术堆栈在 Azure 平台上工作。我同意,特定实现语言的优雅总是有帮助的。
    猜你喜欢
    • 2011-07-07
    • 2012-07-11
    • 2011-08-12
    • 2015-02-23
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    相关资源
    最近更新 更多