(1)从写屏障的角度来说,ES可以部分支持一致性,一致性在分布式的环境中实现的方式有多种,涉及到几个概念,对一个操作至少执行一次,绝对只执行一次,当然还可以自己设计,例如不知道执行与否,就是我会执行但不知道执行结果。扯远了,如果要绝对只执行一次,在实现以及性能上都会有一些折扣,作者采用的是至少执行一次,怎么讲呢,至少执行一次所遵从的原则是必须经过了写屏障,如果没经过写屏障,那么我们可以认为这是无效的,经过了写屏障,系统宕机,可以通过ES重新发起事件。这里执行的就是Domain Event。
既然是至少执行一次,那就会有幂等的处理,作者设计非常灵活,允许使用者自己来装配,在作者的Sample中,使用了MSSQLSERVER来持久化Event,通过MSSQLSERVER中的唯一约束做乐观锁来做到幂等。
在聚合根的内部采用乐观锁来消除幂等,可以在很多个地方使用乐观锁,不管是ENode框架本身提供的,例如在Command Store、Event Store处由SQLSERVER来实现,也可以通过ZooKeeper实现,作者也提供了分布式悲观锁的接口以及采用SQLSERVER的实现,乐观锁就像是一个检查点,台湾人喜欢称这种检查点为机关,我们可以设置合适位置设置合适数量的机关来检查并发。
(2)对应关系数据库的隔离性,在作者的设计中,是按照聚合根来隔离并发的。
使用了聚合根的粒度来实现隔离,在聚合根内部采用了乐观锁或者悲观锁,减小了锁的粒度,来换取性能的提升。
在作者的设计图中还未完全标注出一些组件,
CommandHandler,EventHandler,ApplicationMessageHandler,ExceptionMessageHandler,不是很准确,有兴趣的朋友可以自行查看源代码。
Command、Event是DDD的领域语言
ApplicationMessage、Exception是作者在框架设计的框架领域语言
这些都是作为底层的可传递的消息,可以理解为分布式的消息,上面罗列的Handler都是作者默认实现的,采用的是Actor模式,都是有自己的MailBox,那么其实现就是顺序的并且是单线程的。在某一时刻,单个的系统实例中,Command、Event、ApplicationMessage、Exception都是在并行,但他们内部是只有一个在运行实际的逻辑。这也是可以装配的。