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

发布于 2024-09-09 06:04:33 字数 576 浏览 2 评论 0原文

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

命令处理程序最终会在使用 NHibernate 等工具保存的对象上设置属性,因此我们最终会对数据库进行更新。

我的主要问题是:从数据库性能的角度来看,发出单个 UPDATE 语句更有意义还是发出 5 个不同的 UPDATE 语句更有意义?

我喜欢命令处理程序作为事务边界的想法。要么它有效并且事务被提交,要么它不起作用并且事务被回滚(并且我们可能重新排队以重试)。每个命令的成功或失败与其他命令无关。

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

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

Let's take an example UI for editing Customer information. The user edits 5 fields and presses "submit". Because we're good abstractionists, we've taken the edits to the 5 fields and make them different commands (describing the edit to a particular field).

The command handlers end up setting properties on objects that are persisted with a tool such as NHibernate, so we end up with doing an UPDATE against the database.

My main question is: from a database performance point-of-view, does it make more sense to issue a single UPDATE statement or is it okay to issue 5 different UPDATE statements?

I like the idea of a command handler being a transactional boundary. Either it works and the transaction is committed, or it doesn't and the transaction is rolled back (and we possibly re-queue to try again). The success or failure of each command is independent from the other.

The other approach might be to wrap the handling of these commands into a single database transaction, so that when NHibernate decides to flush it ends up sending a single UPDATE. But this makes the handling of the commands an all-or-nothing type deal, and I can't necessarily execute them asynchronously.

But if I wanted to make sure all of the commands executed properly, and rollback entirely in the case of failure? Maybe there is a single distributed transaction containing many smaller transactions? This could lead to database contention, increasing the risk of deadlocks, which slows down processing (further increasing the risk of deadlocks). But at the same time, consistency is key. I suppose it's a trade off between availability and consistency (see CAP).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

饮湿 2024-09-16 06:04:33

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

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

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

From a database perspective it is almost always better to issue a single update - but it depends on the context whether it really matters or not.

However, I'm not sure that as 'a good abstractionist' you'd really want to issue 5 commands when 5 fields get edited. What you really want to do in DDD is issue a single command for each logical operation that a user is doing through the UI. Usually this is just one per operation, although it could be more than one for more complex scenarios. To take a trivial example, if someone is updating their address you don't have one command for each field - you have a command for updating an address.

The lowest level of granularity that you have will be a command, so whatever is in the command handler needs to be wrapped in a transaction. What we do is put commands into a unit of work so when we issue more than one command they either all pass or all fail. At the end we commit the transaction, meaning any changed objects (for us it's the aggregate root plus events as we're using event sourcing) get persisted. If you're using NHibernate to do this, it will potentially do it one operation - although of course that's down to what you're doing with persistance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文