使用 DDD 更新多个实体
我正在使用 Spring Boot、Java 和 JPA 开发一个应用程序。我选择 DDD,它有多个模块:应用程序、域和基础设施层。该域是纯 Java 语言。
我有一个域实体帐户
。一个用户可以拥有多个帐户。帐户具有类型和状态
,但只有一个帐户可以处于“活动”状态,其余帐户必须处于“非活动”状态。如果我想更改用户的一个帐户的状态,那么我必须更改两个帐户。将“活动”一项设置为“非活动”,将“非活动”一项设置为“活动”。这就带来了事务管理。我不知道在域层中处理此问题的正确方法是什么。
enum State {
ACTIVE, INACTIVE
}
class Account {
private String userId;
private State state;
private String type;
}
class AccountService {
Account activate(Account accountToActivate) {
// various checks
// 1. inactivate active -> save in JPA repo
// 2. activate accountToActivate -> save in JPA repo
// 1 + 2 should be in transaction
// return activatedAccount
}
}
- 我认为如果第二个任务失败,我应该编写一些回滚行为。但另一方面,这也会带来一些严重的复杂性。
- 使用 Springs @Transactional 乍一看似乎是一件好事,但我相信从长远来看它会带来其他问题。
我应该重新设计我的聚合吗?我想不出其他的解决方案。你会如何解决这个问题?你有什么经历?
I am working on an application with Spring Boot and Java and JPA. I am going with DDD and it has multiple modules, the application, the domain, and the infrastructure layer. The domain is in plain Java.
I have a domain entity Account
. One user can have multiple accounts. Accounts have a type and State
but only one account can be 'Active' the rest needs to be 'Inactive'. If I want to change the state of one of the accounts of a user then I have to change two accounts. The 'Active' one to 'Inactive' and the 'Inactive' one to 'Active'. This brings up transactional management. I don't know what would be the proper way to handle this in the domain layer.
enum State {
ACTIVE, INACTIVE
}
class Account {
private String userId;
private State state;
private String type;
}
class AccountService {
Account activate(Account accountToActivate) {
// various checks
// 1. inactivate active -> save in JPA repo
// 2. activate accountToActivate -> save in JPA repo
// 1 + 2 should be in transaction
// return activatedAccount
}
}
- I thought I should write some rollback behavior if the second task fails. But on the other hand, it would bring some serious complexity.
- Using Springs
@Transactional
looks like a good thing at first but I believe it would bring in other problems in the long run.
Should I redesign my aggregate? I cannot think of a different solution. How would you solve this? What are your experiences?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您有一组必须始终一致的事物,那么该组事物必须是同一个“聚合”的一部分。埃文斯对聚合的定义:
这并不必然意味着您的所有帐户实体都需要属于同一聚合。可能您的帐户聚合在那里,而您的用户聚合在这里保存活动帐户的标识符。或者,用户的活动帐户历史记录可能是独立于用户的聚合本身。
有很多可能的答案,具体取决于系统的其他部分关心“活动”帐户,失败会对业务产生什么影响,等等 在。
If you have a set of things that must always be in agreement, then that set of things must be part of the same "aggregate". Evans's definition of aggregate:
That doesn't necessarily mean that all of your account entities need to be part of the same aggregate. It could be that your account aggregates are over there, and your User aggregate over here holds an identifier for the active account. Or it could be that the user's history of active accounts is an aggregate all by itself, separate from the user.
Lots of possible answers, depending on what other parts of the system care about "active" accounts, what is the business impact of having a failure, and so on.
您的帐户类看起来像 ORM DPO,而不是 DDD 实体。特别是状态枚举并不是业务逻辑的良好对象建模。这是适合您的业务约束的 DDD 模型的一个更好的示例:
如何将该模型持久化并转换为关系模型(或存储在 NoSQL 数据库中的 JSON 文档、通过 FTPS 访问的 XML 文件或任何其他外来持久化机制),超出了 DDD 的范围,是基础设施层的责任。
Your account class looks like an ORM DPO, not a DDD entity. Especially the state enum is not a good object modeling of your business logic. This is a better example of DDD model for your business contraints:
How this model is persisted and translated into a relational model (or a JSON document stored in a NoSQL database, an XML file accessed through FTPS, or any other exotic persistence mechanism), is out of the scope of DDD and is the responsibility of the infrastructure layer.