我还是什么,必须与CQRS建筑风格基本(和解决)问题挣扎根源是什么?实现在CQRS
以一个预订应用程序为例。它可以让您预订音乐会的门票,电影席位或餐厅的桌子。在所有情况下,只会出售有限数量的“商品”。
让我们假设事件或地点非常受欢迎。当新的事件或时间段的销售开放时,预订开始很快到达 - 可能每秒钟很多。
在查询方面,我们可以大规模地进行扩展,并且保留放在队列中由独立组件异步处理。首先,当我们从队列中取消预订命令时,我们将接受它们,但是在某个时候,我们将不得不开始拒绝其余的。
我们如何知道何时达到极限?
对于每个Reservation Command,我们都必须查询某种商店以确定我们是否可以容纳请求。这意味着我们需要知道当时我们已经收到了多少预订。
但是,如果域存储是非关系数据存储,例如, Windows Azure的表存储,我们不能很好地做了SELECT COUNT(*) FROM ...
一种选择是保持单独的聚合根,仅仅保持当前计数的轨道,就像这样:
- AR:预定(谁多少?)
- AR:事件/时隙/日期(汇总数)
第二聚合根将是第一个的非规范化的聚集,但是当underlyi ng数据存储不支持事务,那么它们很可能在高容量场景中出现不同步(这正是我们首先要解决的问题)。
一个可能的解决方案是序列化处理预留命令,以便一次只处理一个,但这违背了我们的可扩展性(和冗余)目标。
这样的场景让我想起了标准的“断货”的情况,但不同的是,我们不能很好地把保留在后的顺序。一旦一个事件售罄,它已经售罄,所以我看不出会有什么补偿行动。
我们如何处理这种情况?
我同意设定期望值也是一个重要的部分,但我把它看作一个给定的 - 这在技术上很容易处理。问题是:在没有锁定和交易的情况下,我们如何可靠且一致地减少大量并发情况下剩余可用座位/票的柜台? – 2010-12-04 22:58:42
柜台只是作为告知客户的方式,而不是他们要求的最终答案。你总是需要检查数据库以确认。如果您有多个后台工作人员处理预留请求,则计数器确实需要一个锁(当您调用增量(键)或减量(键)时,memcached是原子的 - 因此在这里没有问题)。但是考虑到你的空间资源情况(比如音乐会的门票),柜台上锁定的几毫秒是可以接受的(请记住,这将快速缩小为零,并且新请求将被拒绝) – 2010-12-04 23:04:41
如果我采用该路线(我可能),这个问题归结为:你如何*取消对Azure Tables的锁定?我不认为你可以... – 2010-12-06 09:29:31