加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

领域驱动设计 – CQRS /事件采购,如何获得一致的数据应用业务规

发布时间:2020-12-14 18:56:05 所属栏目:资源 来源:网络整理
导读:有时我正在使用CQRS模式和Event Sourcing开发一个小型项目. 我有一个结构性的问题,我不知道要解决什么解决方案. 想像下面的例子: 发送一份指令,其中包含银行客户存入一定金额的信息(DepositCommand). 在命令处理程序/ Entity / Aggregate(对于讨论来说不重
有时我正在使用CQRS模式和Event Sourcing开发一个小型项目.
我有一个结构性的问题,我不知道要解决什么解决方案.

想像下面的例子:
发送一份指令,其中包含银行客户存入一定金额的信息(DepositCommand).
在命令处理程序/ Entity / Aggregate(对于讨论来说不重要)必须应用业务规则;
如果客户是前10%的客户之一,赢得一些奖金.

问题是如何获得最新,一致的数据,以了解客户在存款之后是否在前10%.

>我不能使用事件存储,因为不可能进行这样的查询;
>我不知道如果我可以使用阅读模型,因为不是100%
确定是最新的.

如果您需要数据库中的数据来应用业务规则,您该怎么做?如果我不注意最新的数据,我遇到了可能性
给两个不同的客户奖

期待听到你的意见.

解决方法

汇总要求作出业务决策的任何信息应作为汇总状态的一部分存储.因此,当收到命令以将钱存入客户的帐户时,您应该已经拥有该客户端的当前/更新状态,该状态可以包含其每个帐户的当前余额.

我也建议一个汇总不应该去阅读模型来提取信息.根据您尝试实现的内容,您可以从读取模型(状态不重要)中增加详细信息来丰富命令,但聚合本身应该从自己已知的状态中拉出.

编辑

重读了这个问题后,我意识到你正在谈论跨多个聚合的跟踪状态.这属于传奇的境界.您可以创建一个追踪门槛需要达到前10%的传奇.因此,每当客户进行存款时,传奇都可以跟踪排名的位置.如果该客户端跨越了线程,您可以从saga发布一个命令,以表明它们符合所需的标准.

在您的情况下,您的传奇可能会追踪所有存款的总额,所以在进行存款时,可以决定客户现在是否处于前10%.其他问题你可能会问自己…如果客户存入$X的金额,并立即宽幅$Y下降在threashold之下;应该发生什么等等.

非常粗糙的聚集/传奇手柄方法…

public class Client : Aggregate
{
    public void Handle(DepositMoney command)
    {
        // What if the account is not known? Has insufficient funds? Is locked? etc...
        // Track the minimum amount of state required to make whatever choice is required.
        var account = State.Accounts[command.AccountId]; 

        // Balance here would reflect a point in time,and should not be directly persisted to the read model;
        // use an atomic update to increment the balance for the read-model in your denormalizer.
        Raise(new MoneyDeposited { Amount = command.Amount,Balance = account.Balance + command.Amount }); 
    }

    public void Handle(ElevateClientStatus command)
    {
        // you are now a VIP... raise event to update state accordingly...
    }
}

public class TopClientSaga : Saga
{
    public void Handle(MoneyDeposited e)
    {
        // Increment the total deposits... sagas need to be thread-safe (i.e.,locked while state is changing).
        State.TotalDeposits += e.Amount;

        //TODO: Check if client is already a VIP; if yes,nothing needs to happen...

        // Depositing money itself changes the 10% threshold; what happens to clients that are no longer in the top 10%?
        if (e.Balance > State.TotalDeposits * 0.10)
        {
            // you are a top 10% client... publish some command to do whatever needs to be done.
            Publish(new ElevateClientStatus { ClientId = e.ClientId,... });
        }
    }

    // handle withdrawls,money tranfers etc?
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读