简体   繁体   English

DDD CQRS并发问题

[英]DDD CQRS Concurrency issue

We have set up an architecture based on DDD and CQRS. 我们已经建立了基于DDD和CQRS的体系结构。 Additionally we have a restful API with an OAUTH implementation for our clients to connect to. 另外,我们有一个带有OAUTH实现的静态API,供我们的客户连接。 Our clients connect to our API and perform operations on behalf of their clients. 我们的客户连接到我们的API并代表他们的客户执行操作。 Their clients are represented by profiles on our side. 他们的客户由我们这边的个人资料代表。

We don't have a good solution for the following problem. 对于以下问题,我们没有好的解决方案。 Clients are able to create a profile by calling a method on our API. 客户可以通过在我们的API上调用方法来创建配置文件。 The problem is that we need to guarantee the uniqueness of the profiles. 问题在于我们需要保证配置文件的唯一性。 So what we currently do is check for an existing profile in the read model, create a command if it doesn't exist and return the profile ID back to the client so they can perform other API calls. 因此,我们当前要做的是检查读取模型中的现有概要文件,如果不存在则创建一个命令,然后将概要文件ID返回给客户端,以便他们可以执行其他API调用。

When a client performs multiple calls in rapid succession, a profile is created twice instead of once due to an out of date read model. 当客户端快速连续执行多个呼叫时,由于过期的读取模型,配置文件将创建两次,而不是一次。 We don't want that, but how do we resolve this issue? 我们不想要那样,但是我们如何解决这个问题呢?

We have thought about creating a saga to prevent more than one profile being created in the domain, but that is still problematic because we need to return the same profile ID to the client if their request is the same. 我们已经考虑过创建一个传奇,以防止在域中创建多个配置文件,但这仍然是有问题的,因为如果他们的请求相同,我们需要将相同的配置文件ID返回给客户端。

Any thoughts? 有什么想法吗?

Commands are not supposed to return results. 命令不应返回结果。

What you can do is create a command that includes the ID of the new profile, if it is a GUID. 您可以做的是创建一个包含新配置文件ID的命令(如果它是GUID)。 If you are using a seeded identity column of some sort, of course this won't work. 如果您使用某种种子身份列,那么这当然是行不通的。

But say that your ID is a GUID. 但是请说您的ID是GUID。 Then you can pass a GUID in the command to the back end. 然后,您可以在命令中将GUID传递给后端。 The back end will create the new profile only if the GUID doesn't already exist -- and you have guaranteed unicity. 仅当GUID不存在时,后端才会创建新的配置文件-并且您已保证唯一性。

From what I understand from the CQRS pattern, the command layer should not make use of the read model to take any decision. 根据我对CQRS模式的了解,命令层不应利用读取模型做出任何决定。 The command layer do its processing based on the domain it self. 命令层基于其自身的域进行处理。 Not based ont he read model. 不基于他阅读模型。 Validation is always made ont the domain data. 验证始终在域数据上进行。 You profil creation command handler should check for the pre existence of the profil in the domain and not in the read model. 您的概要文件创建命令处理程序应检查域中是否存在概要文件,而不是在读取模型中。

That's correct. 没错 Command should not rely on ReadModel, because of Eventually Consistent principle of ReadModel. 由于ReadModel的最终一致性原理,因此命令不应依赖ReadModel。

Just use your Domain in commands to make decision based on it. 只需在命令中使用您的Domain即可做出决定。

Usually CQRS + EventSourcing repositories have very few methods, but on of them is GetById(Guid id). 通常,CQRS + EventSourcing存储库只有很少的方法,但其中一个是GetById(Guid id)。 You can use it to check if such entity is already present in domain. 您可以使用它来检查域中是否已存在该实体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM