承接上篇文章谈到的aggregate的设计策略。aggregate是用来保证数据(*注: 之前的文章都是用数据完整性这个说法,其实是想表达data consistency这个意思,查了一下翻译,感觉还是数据一致性比较贴切)一致性的一个单位,但是如果设计大的aggregate的话,容易产生并发问题和资源浪费等问题。所以在考虑数据一致性的同时。我们要尽量设计小的aggregate。
另外自然会碰到这样的问题,aggregate的内部数据一致性由aggregate来保证。那aggregate之间会不会存在数据一致性呢?尤其在尽量设计小aggregate的前提下,这个问题好像更加容易发生。
跨aggregate的数据一致性
用例子来说明问题吧。
比如有一个类似博客的网站的功能。有用户User和文章post。
class User {
private UserId userId;
private String email;
private String username;
private AccountStatus accountStatus;
public void deactivate(){
accountStatus = AccountStatus.DEACTIVATED;
}
}
这里为了说明问题,我们就定义User的一个行为,注销deactive。
class Post {
private PostId postId;
private UserId authorId;
private String text;
private PostStatus postStatus;
private Long views;
public void view(UserId userId) {
if(userId == authorId){
throw new CannotAddViewToYourOwnPostException(postId);
}
this.likes = this.likes + 1;
}
public void delete(UserId userId){
if(userId != authorId){
throw new IllegalAccessException(postId, userId);
}
postStatus = PostStatus.DELETED;
}
}
Post呢,简单起见也定义两更行为,阅览(记录阅览次数)和删除。如果你觉得物理删除是个邪恶的行为。那就定义一个状态来表示删除,例子中我们定义了一个枚举。
接下来要实现一个用例。当一个User账号删除后,与User关联的Post也必须删除。当User处在注销状态下,User的Post处在废删除状态是不合理的。这又是个数据一致性需要保障。
如何保障跨aggregate的数据一致性
先别想太多,就按普通的思路走,把对多个aggregate的操作写进一个事务不就行了?
class AuthorApplica