CQRS(Axon) 撤销功能怎么设计?

目前项目需要设计一个撤销(undo)的功能,传统的java 应用的好像比较简单,主要利用设计模式中的comand命令行模式或者Memento备忘录模式,把需要操作的pojo简单备份一份即可,需要undo时,再从list中取回该备份对象,直接重设回即可。

但是目前我们项目采用的确是CQRS(Axon框架),有多个业务异常复杂的domain需要维护,如果undo的话,不仅需要DTO(数据库层)需要回退(使用command或者Memento模式?),而且需要回退domain中的对象状态。有很多疑问:

1.能否利用CQRS自身的机制实现?比如快照,事件回放之类的。但是这样是否会丢失某些状态?比如我做了A操作,修改了A状态,然后做了B操作,修改了B状态,最后再做了C操作,然后修改了domain中的C状态。现在,我undo B操作,domain回退到了A状态时,是否C状态丢失了?

2.想在domain中添加previousXXX一类的field,每一次状态改变之前,维护一份该状态的上一个版本,但是这样做的缺点显而易见,有太多的状态需要维护,几十个,很繁琐易错

大家有没有什么好的思路,不吝赐教,谢谢


[该贴被tanleihaoren于2012-08-02 10:35修改过]

2012-08-02 10:15 "@tanleihaoren"的内容
目前项目需要设计一个撤销(undo)的功能,传统的java 应用的好像比较简单 ...

你可以采用cache方式进行同步,参看 http://www.jdon.com/44212


你说的撤销其实不应该是撤销event,因为eventstore储存的event是不能被删除的,你说的撤销应该也是产生一个 undo event ,不知道你明白没。

eventstore是单向的储存和查询(或回放),而不能删除。

2012-08-02 16:21 "@brighthas"的内容
你说的撤销其实不应该是撤销event,因为eventstore储存的event是不能被删除的,你说的撤销应该也是产生一个 undo event ,不知道你明白没。

eventstore是单向的储存和查询(或回放),而不能删除。 ...

谢谢,目前我们确实在考虑产生一个undo的event,但是这个event中就需要带有所有last的状态,感觉这样的话参数会很多。

比如:
第一步:A操作--》更新domain中的A状态
第二步:B操作--》更新domain中的B状态
第三步:C操作--》更新domain中的C状态
第四步:D操作--》更新domain中的D状态(和A操作相关的一个操作,好比是级联操作)

现在我们需要undo A操作,这样的话,也同时需要undo D操作,但是BC操作却不需要改变。

[该贴被tanleihaoren于2012-08-02 16:57修改过]

2012-08-02 16:48 "@tanleihaoren"的内容
谢谢,目前我们确实在考虑产生一个undo的event,但是这个event中就需要带有所有last的状态,感觉这样的话参数会很多。 ...

准确的说,和event store没太多关系,你不能理解是事件的撤销,事件是无法撤销的,撤销undo动作也是一个事件,我的实现如下:



var do = ... // Domain Object
do.a();
// publish aEvent
do.onA(aEvent);
// 内部监听这个aEvent 同时,记录一下。
do.undoA() ;
// 回轮到前一个属性值。同时产生一个 undoA Event.


[该贴被brighthas于2012-08-02 17:47修改过]

呃。。。想问一下你们做的啥类型的项目,平时没接触过“撤销”这样的需求。。。

如果按Event来处理,也可以把undo作为Event处理,undo或者redo都可以,关键是Event触发的动作处理。