Transactions 命令处理程序和执行的事务边界是什么?

Transactions 命令处理程序和执行的事务边界是什么?,transactions,domain-driven-design,cqrs,Transactions,Domain Driven Design,Cqrs,让我们以编辑客户信息的UI为例。用户编辑5个字段并按“提交”。因为我们是优秀的抽象主义者,所以我们对5个字段进行了编辑,并使用不同的命令(描述对特定字段的编辑) 命令处理程序最终会在使用诸如NHibernate之类的工具持久化的对象上设置属性,因此我们最终会对数据库进行更新 我的主要问题是:从数据库性能的角度来看,发出一个UPDATE语句是否更有意义,或者发出5个不同的UPDATE语句是否可以 我喜欢将命令处理程序作为事务边界的想法。要么它工作并且事务被提交,要么它不工作并且事务被回滚(并且我们

让我们以编辑客户信息的UI为例。用户编辑5个字段并按“提交”。因为我们是优秀的抽象主义者,所以我们对5个字段进行了编辑,并使用不同的命令(描述对特定字段的编辑)

命令处理程序最终会在使用诸如NHibernate之类的工具持久化的对象上设置属性,因此我们最终会对数据库进行更新

我的主要问题是:从数据库性能的角度来看,发出一个UPDATE语句是否更有意义,或者发出5个不同的UPDATE语句是否可以

我喜欢将命令处理程序作为事务边界的想法。要么它工作并且事务被提交,要么它不工作并且事务被回滚(并且我们可能重新排队重试)。每个命令的成功或失败是相互独立的

另一种方法可能是将这些命令的处理打包到一个数据库事务中,这样当NHibernate决定刷新时,它就会发送一个更新。但是这使得命令的处理成为一种全有或全无类型的处理,我不一定能异步执行它们


但是如果我想确保所有的命令都正确执行,并且在失败的情况下完全回滚?也许有一个分布式事务包含许多较小的事务?这可能导致数据库争用,增加死锁风险,从而降低处理速度(进一步增加死锁风险)。但与此同时,一致性是关键。我认为这是可用性和一致性之间的折衷(见CAP)。

从数据库的角度来看,发布一次更新几乎总是更好的,但这取决于上下文是否真的重要

然而,我不确定作为一个“优秀的抽象主义者”,你是否真的想在编辑5个字段时发出5个命令。在DDD中,您真正想要做的是为用户通过UI执行的每个逻辑操作发出一个命令。通常,每个操作只有一个,但对于更复杂的场景,可能不止一个。举一个简单的例子,如果有人正在更新他们的地址,那么每个字段并没有一个命令,而是有一个更新地址的命令


您拥有的最低粒度级别是命令,因此命令处理程序中的任何内容都需要包装在事务中。我们所做的是将命令放入一个工作单元,因此当我们发出多个命令时,它们要么全部通过,要么全部失败。最后,我们提交事务,这意味着任何更改的对象(对于我们来说,它是聚合根加上事件,因为我们正在使用事件源)都会被持久化。如果您使用NHibernate来执行此操作,它可能只执行一次操作—当然这取决于您使用持久性所做的操作。

从数据库的角度来看,几乎总是最好只执行一次更新—但这取决于上下文是否真的重要

然而,我不确定作为一个“优秀的抽象主义者”,你是否真的想在编辑5个字段时发出5个命令。在DDD中,您真正想要做的是为用户通过UI执行的每个逻辑操作发出一个命令。通常,每个操作只有一个,但对于更复杂的场景,可能不止一个。举一个简单的例子,如果有人正在更新他们的地址,那么每个字段并没有一个命令,而是有一个更新地址的命令


您拥有的最低粒度级别是命令,因此命令处理程序中的任何内容都需要包装在事务中。我们所做的是将命令放入一个工作单元,因此当我们发出多个命令时,它们要么全部通过,要么全部失败。最后,我们提交事务,这意味着任何更改的对象(对于我们来说,它是聚合根加上事件,因为我们正在使用事件源)都会被持久化。如果您使用NHibernate来执行此操作,它可能只执行一个操作—当然这取决于您使用persistence执行的操作。

我相信您对多个命令的看法是正确的;为单个逻辑操作发出命令,例如“更新客户的电话号码”或“更新客户的姓名”(可能是多个字段)。但是为什么不是每个命令都是工作单元呢?例如,如果这些命令被发送到其他进程以异步执行,则这可能是有意义的。我们确实执行封装在一个事务中的命令,以受益于NHibernate对要执行多少SQL语句的管理。但由于这是全部或全部,我觉得它打破了一个命令的自然工作单元;为单个逻辑操作发出命令,例如“更新客户的电话号码”或“更新客户的姓名”(可能是多个字段)。但是为什么不是每个命令都是工作单元呢?例如,如果这些命令被发送到其他进程以异步执行,则这可能是有意义的。我们确实执行封装在一个事务中的命令,以受益于NHibernate对要执行多少SQL语句的管理。但由于这是全部或全部,我觉得它打破了命令的自然工作单元。