一个command产生多个事件产生的问题!

13-07-29 fengweili
              

板桥老师你好:

看了你写的AngularJS+Restful+CQRS的文章,有以下问题想请求?

1.Restful对于PUT,POST,DELETE得到的应该是Command吧?

2.如果一个Command产生多个事件,如何保证这几个事件的原子性,其中一个失败了,这种情况如何重新播放事件和还原?

              

banq
2013-07-29 15:01

应该一个Command产生一个事件,命令是用户让系统做什么,事件是系统已经做了什么,事件促使状态变化,记录事件相当于记录状态的变化历史,回放事件实际是回放状态的变化历史。

REST的命令是抽象的命令,类似CRUD命令一样,实际系统中,用户让系统的做的命令是和业务领域有关,当这个命令被分类到POST PUT或DELETE中时,REST这些命令其实是粗粒度命令,和业务领域关系不大,代表一种命令通道。

参考:http://www.jdon.com/45617

[该贴被banq于2013-07-29 15:02修改过]

fengweili
2013-07-29 16:16

按照AngularJS+Restful+CQRS这种架构,做一个转账的的应用,是这样:

1.先从AngularJS发扣除命令-->Restful

2.再从AngularJS发增加命令->Restful

还是这样:

1.从AngularJS发送转帐命令->Restful然后生成两个子命令(扣除与增加),再分别产生对应事件。

另:

1.为什么命令与事件是一对一关系,只是为了简化设计?

2.对于像登陆、退出等动词,Restful设计方面有什么技巧吗?

谢谢解答!

banq
2013-07-29 16:46

2013-07-29 16:16 "@fengweili

"的内容

做一个转账的的应用,是这样 ...

都不是,大概是这样:

1. AngularJS先GET获得当前帐号信息

2.根据帐号信息中提供的URL发出转账的POST命令:

POST /transactions

然后加入参数 from=1&to=2&amount=500.00

见:http://www.jdon.com/41716

3.第二步的POST命令直接递交到转账服务,transactionService.

在转账服务中,有二种实现方式:

1. DCI+面向函数风格,直接在转账服务的方法中实现,将源账户和目标帐号看成两个角色TransferMoneySourceAccount和TransferMoneyDestinationAccount,需要通过事务机制。见:http://www.jdon.com/37976

2.DDD聚合体+EventSourcing方式, 转账服务委托聚合根实现,TransactionAggregate作为聚合根实体,转账是这个实体的一个行为方法,转账命令到激活这个方法,在这个方法内部将产生一个转账事件。见:

http://simon-says-architecture.com/2013/03/07/modelling-accounting-ledger-event-driven/

http://simon-says-architecture.com/2013/03/22/modelling-accounting-ledger-event-driven-2/

更正一下,我前面提到一个命令一个事件,是指一个命令对应上游事件,一旦上游事件进入聚合根内部,变成很多事件流分支,比如

var tx = new Transaction();
tx.Post(amount, fromAccount, toAccount);
transactionRepository.Store(tx);
<p>

这是调用Transaction这个聚合根的post方法。方法内部代码:

public void Post(decimal amount, string fromAccount, string toAccount)
{
   this.Apply(new AccountDebited(amount, fromAccount));
   this.Apply(new AccountCredited(amount, toAccount));
}
<p>

将转账命令(转账上游事件)分为两个事件,AccountDebited和AccountCredited,账户借款和账户贷款,这样保证借贷平衡。然后根据借贷状态切换,还有更多子状态,EventStore应该是这些和状态直接有关的事件,间接有关事件没有必要记录,这样在事件回放时才能重现状态真实改变历史。

[该贴被banq于2013-07-30 17:08修改过]