实施CQRS基于设定的约束 [英] Implementing set-based constraints in CQRS

查看:153
本文介绍了实施CQRS基于设定的约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还是什么必须是基本的(和解决)有关CQRS建筑风格的问题挣扎:

I'm still struggling with what must be basic (and resolved) issues related to CQRS style architecture:

我们如何实现依赖于一组总结罗茨业务规则?

How do we implement business rules that rely on a set of Aggregate Roots?

取,作为一个例子,一预定的应用程序。它可以使您预订的门票演唱会,座位电影或桌子上的餐厅。在所有的情况下,只有将是的数量有限的项目出售

Take, as an example, a booking application. It may enable you to book tickets for a concert, seats for a movie or a table at a restaurant. In all cases, there's only going to be a limited number of 'items' for sale.

让我们想象一下,该事件或地方非常受欢迎。当销售打开一个新的事件或时隙,预订开始非常迅速到达 - 也许每秒许多

Let's imagine that the event or place is very popular. When sales open for a new event or time slot, reservations start to arrive very quickly - perhaps many per second.

在查询方面,我们可以大规模扩展,并预订放在一个队列将由一个独立的组件异步处理。起初,当我们从队列中拉出保留命令,我们会接受他们,但在特定的时间,我们将要开始的拒绝休息

On the query side we can scale massively, and reservations are put on a queue to be handled asynchronously by an autonomous component. At first, when we pull off Reservation Commands from the queue we will accept them, but at a certain time we will have to start rejecting the rest.

我们怎么知道,当我们到达极限?

How do we know when we reach the limit?

对于每一个保留命令,我们将要查询某种店弄清楚我们是否能够满足要求。这意味着,我们需要知道有多少保留,我们当时已经收到。

For each Reservation Command we would have to query some sort of store to figure out if we can accommodate the request. This means that we will need to know how many reservations we have already received at that time.

然而,如果域商店是一个非关系数据存储诸如例如Windows Azure的表的存储,我们不能很好地做 SELECT COUNT(*)FROM ...

However, if the Domain Store is a non-relational data store such as e.g. Windows Azure Table Storage, we can't very well do a SELECT COUNT(*) FROM ...

一个选择是保持独立的聚合根,简单地保持当前计数的轨迹,像这样的:

One option would be to keep a separate Aggregate Root that simply keeps track of the current count, like this:


  • AR:预订(?谁多少)

  • AR:事件/时隙/日(合计数)

第二聚合根是第一位的非规范化的聚集,但是当底层数据存储不支持事务处理,那么它很可能是这些都可以在大批量的情况不同步(也就是我们试图在第一时间解决)。

The second Aggregate Root would be a denormalized aggregation of the first one, but when the underlying data store doesn't support transactions, then it's very likely that these can get out of sync in high-volume scenarios (which is what we are trying to address in the first place).

一个可行的办法是为连载预约的处理命令,以便只有一次的处理,但是这有悖于我们的可扩展性(和冗余)。

One possible solution is to serialize handling of the Reservation Commands so that only one at a time is handled, but this goes against our goals of scalability (and redundancy).

这样的场景让我想起了标准的断货的情况,但不同的是,我们不能很好地把预约背面秩序。一旦事件已经卖完了,它的卖完了,所以我不能看到一个补偿动作将是什么。

Such scenarios remind me of standard "out of stock" scenarios, but the difference is that we can't very well put the reservation on back order. Once an event is sold out, it's sold out, so I can't see what a compensating action would be.

我们如何处理这样的情况?

How do we handle such scenarios?

推荐答案

想着这一段时间它终于醒悟过来了,潜在的问题是CQRS少相关比它是在非trasactional <后/ STRONG>的不同REST服务性质。

After thinking about this for some time it finally dawned on me that the underlying problem is less related to CQRS than it is to the non-trasactional nature of disparate REST services.

实际上它归结为这个问题:如果你需要更新一些资源,你怎么保证一致性,如果第二次写操作失败

Really it boils down to this problem: if you need to update several resources, how do you ensure consistency if the second write operation fails?

让我们想象一下,我们要写入更新资源A和B资源的序列。

Let's imagine that we want to write updates to Resource A and Resource B in sequence.


  1. 资源共享的成功更新

  2. 要更新资源B上的尝试失败

第一次写操作不容易被回滚一个异常的脸,所以我们能做些什么?捕捉和SUP pressing例外执行对资源共享的一个补偿动作是不是一个可行的选择。首先,它是复杂的实现,但其次它不是安全的:如果一个异常发生,因为一个失败的网络连接会发生什么?在这种情况下,我们不能写对资源共享的一个补偿措施无论是。

The first write operation can't easily be rolled back in the face of an exception, so what can we do? Catching and suppressing the exception to perform a compensating action against Resource A is not a viable option. First of all it's complex to implement, but secondly it's not safe: what happens if the first exception happened because of a failed network connection? In that scenario, we can't write a compensating action against Resource A either.

关键在于明确的幂等。虽然Windows Azure的队列不保证的只有一次语义,他们做担保的至少一次语义。这意味着,在间歇异常的脸,该消息稍后将重播

The key lies in explicit idempotency. While Windows Azure Queues don't guarantee exactly once semantics, they do guarantee at least once semantics. This means that in the face of intermittent exceptions, the message will later be replayed.

在previous的情况下,这是那么会发生什么:

In the previous scenario, this is what happens then:


  1. 资源共享的尝试更新。然而,在检测到重放所以A的状态不受影响。然而,写操作成功。

  2. 资源B被成功更新。

在所有的写操作都是幂等,最终一致性可以是消息实现回放

When all write operations are idempotent, eventual consistency can be achieved with message replays.

这篇关于实施CQRS基于设定的约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆