CQRS 架构中 一个事务生成的多个领域event 如何执行

14-06-19 sinaID87521
    

CQRS 架构中 多个事务生成的领域event 谁先执行谁后执行?

https://github.com/banq/jdonframework/blob/master/example/cqrs%2Bes/match/src/main/java/sample/domain/Match.java

@Model
public class Match {
	private String id;
	private Date matchDate;
	private Team teams[] = new Team[2];
	private boolean finished;
	@Inject
	public EventSourcing es;
	public void handle(MatchCreatedEvent matchCreatedEvent) {
		this.id = matchCreatedEvent.getMatchId();
		this.teams[0] = new Team(matchCreatedEvent.getMatchTeamName1());
		this.teams[1] = new Team(matchCreatedEvent.getMatchTeamName2());
		this.finished = false;
	}
	public void startMatch(Date matchDate) {
		if (this.matchDate != null)
			System.err.print("the match has started");
		es.started(new MatchStartedEvent(this.id, matchDate));
	}
	public void handle(MatchStartedEvent event) {
		this.matchDate = event.getMatchDate();
	}
	public void finishWithScore(Score score, Date matchDate) {
		if (this.matchDate == null)
			System.err.print("the match has not started");
		if (finished)
			System.err.print("the match has finished");
		es.finished(new MatchFinishedEvent(this.id, matchDate, score.getHomeGoals(), score.getAwayGoals()));
	}
	public void handle(MatchFinishedEvent event) {
		this.finished = true;
	}
	public String getId() {
		return id;
	}
	public String getHomeTeamName() {
		return teams[0].getName();
	}
	public String getAwayTeamName() {
		return teams[1].getName();
	}
	public boolean isFinished() {
		return finished;
	}
}
<p>

异步框架,通过事件进行异步化.

可能一个事务生成了一场比赛事件MatchStartedEvent1,还有其他实体的事件.比如每个人出场次数+1Event PersonEvent1;

另外一个事务生成了另外两个事件. MatchStartedEvent2 ,PersonEvent2.

然后会处理这些事件,因为MatchStartedEvent1和PersonEvent1之前是属于一个事务的, 那么我的问题是执行两个事件,把Match和Persion的变化持久化到数据库.

.是否也是放在一个事务内执行?

如果不是,如何保证事务内操作的要么全部回滚,要么全部成功的特性

    

banq
2014-06-19 13:12

我不是很清楚你的事务是业务用语还是技术用语,因为我们过去技术影响,可能会将一些技术用语加入到业务中。

事务是一种高一致性的用语,这是从强一致性角度看待问题。建议参考:弱一致性在现实世界中到处存在

CQRS的EventSourcing中将事件作为原子不变量记录,然后根据时间顺序播放本身就已经有事务概念,这个事件流只能播放或追究,不能删除和修改的。

提供你一个英文参考:General-purpose databases that never delete or update data in-place

http://www.cqrs.nu

[该贴被banq于2014-06-19 13:13修改过]

sinaID87521
2014-06-20 13:24

值得是技术上的事务 spring @[author]Transaction[/author] .

jdbc.setAutoCommit(false)

2014-06-19 13:12 "@banq"的内容
时间顺序 ...

对,关键是用什么排序的问题.

时间排序我想过显然是不够严谨的.因为时间是有精度的.总有可能两个事件时间是一样的.

用事件数据库自增id也是错误的.

因为spring @[author]Transaction[/author] 内 ,

事务1 生成Event1 获得的数据库自增id是1

事务2 生成Event2 获得数据库自增id是2.

然后事务2提交.

然后事务1提交.

那后面操作事件的顺序应该是 event id=2 ,然后才是event id=1 .

我有点想不通,如何实现才能保证事件按照事务提交顺序进行操作.

[该贴被sinaID87521于2014-06-20 13:30修改过]

tangxuehua
2014-06-20 20:27

可以去看一下enode的实现。

sinaID87521
2014-06-23 10:10

2014-06-20 20:27 "@tangxuehua"的内容
enode的实现。 ...

感谢你的思路.

看了下,原来这个的目的是解决两个聚合跟的问题.

我重新思考了下,其实person 其实算是聚合跟match下面的一个类.

所以开赛这个动作还是只会产生一个事件.

所以说很多时候一个动作都只是操作的是一个聚合跟.

想咨询下,一般哪些情况一个动作可以操作多个聚合跟.

2Go 1 2 下一页