我们以一个示例UI来编辑客户信息。用户编辑5个字段并按“提交”。因为我们是很好的抽象主义者,所以我们对5个字段进行了编辑,并使它们具有不同的命令(描述对特定字段的编辑)。
命令处理程序最终设置了使用NHibernate等工具持久保存的对象的属性,因此我们最终对数据库进行了更新。
我的主要问题是:从数据库性能的角度来看,发布单个UPDATE语句更有意义,还是可以发出5个不同的UPDATE语句?
我喜欢命令处理程序是事务边界的想法。它可以工作并且事务已提交,或者它没有提交,事务被回滚(我们可能会重新排队再次尝试)。每个命令的成功或失败都是独立的。
另一种方法可能是将这些命令的处理包装到单个数据库事务中,这样当NHibernate决定刷新时,最终会发送一个UPDATE。但这使得处理命令成为一种全有或全无的类型处理,我不一定能异步执行它们。
但是如果我想确保所有命令都正确执行,并且在失败的情况下完全回滚?也许只有一个包含许多小事务的分布式事务?这可能会导致数据库争用,增加死锁风险,从而减慢处理速度(进一步增加死锁风险)。但与此同时,一致性是关键。我认为这是可用性和一致性之间的权衡(参见CAP)。
答案 0 :(得分:4)
从数据库的角度来看,发布单个更新几乎总是更好 - 但它取决于上下文是否真的重要。
但是,我不确定作为“一个好的抽象主义者”,当你编辑5个字段时,你真的想要发出5个命令。您真正想要在DDD中执行的操作是为用户通过UI执行的每个逻辑操作发出单个命令。通常这只是每个操作一个,但对于更复杂的场景,它可能不止一个。举一个简单的例子,如果有人正在更新他们的地址,那么每个字段都没有一个命令 - 你有一个更新地址的命令。
您拥有的最低粒度级别将是一个命令,因此命令处理程序中的任何内容都需要包含在事务中。我们所做的是将命令放入一个工作单元中,因此当我们发出多个命令时,它们全部通过或全部失败。最后我们提交了事务,这意味着任何已更改的对象(对于我们来说,它是聚合根和事件,因为我们正在使用事件源)得到持久化。如果您正在使用NHibernate来执行此操作,它可能会执行一次操作 - 当然这取决于您持续执行的操作。