弹簧数据JDBC删除所有条目并再次插入它们

发布于 2025-02-04 07:13:24 字数 186 浏览 2 评论 0原文

我目前正在使用Spring Data JDBC框架,但我不了解以下行为: 当我有一个总的根源来存储一个孩子列表并加一个孩子时,它会删除所有孩子并再次插入他们。

这意味着,当我的汇总根存储另一个实体的5000个条目并添加一个条目时,它执行5000个删除语句和5001个插入语句。

这会导致绩效问题吗?有没有干净的方法来避免这种行为?

I am currently playing around with the Spring Data Jdbc framework and I don't understand the following behaviour:
When I have an aggregate root that stores a list of children and I add one child, it deletes all children and inserts them again.

This means, when my aggregate root stores 5000 entries of another entity and I add one entry, then it executes 5000 delete statements and 5001 insert statements.

Could that lead to performance issues? Is there a clean way to avoid this behaviour?

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

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

发布评论

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

评论(1

暮光沉寂 2025-02-11 07:13:24

是的,这是当前的行为。是的,如果您有5000个条目的汇总,这将导致性能问题。

但是,如果您有5000个条目的汇总,则使用汇总错误。骨料旨在用作原子单位。聚集体被加载为一件事,它被一件事持续了。无论您做什么,这都会很慢。这样的域应建模为两个单独的聚合物。

当然,即使有较小的聚集体,这也是有代价的。如果成本很重要,并且您的应用程序内部您知道更好的行为,则可以并且应该以自定义方法实施。例如,您可以拥有一个addentry方法,该方法仅执行您在问题中给出的示例的单个插入。

对于隐式问题:为什么春季数据在做这件事?答案是“简单性”。为了避免这种基本方法,人们将需要跟踪总体上实际变化的内容。这基本上就是JPA选择的方法。这意味着您需要对汇总进行参考。您必须处理应用程序中多个实例代表一个实体的情况。这些是使JPA如此复杂的事情。 Spring Data JDBC采用了不同的方法。它基本上是:“我不知道数据库现在处于什么状态,但是一旦完成了持久操作,就必须与应用程序内的汇总状态相匹配

” 。我们目前正在引入相当多的批处理操作,这些操作有可能加快事情的速度。还有一张票可以进行“删除/UPSERT”操作,这应该表现更好。但这仍然会碰到所有行。

Yes this is the current behaviour. Yes if you have an aggregate with 5000 entries this will cause performance problems.

But if you have an aggregate with 5000 entries, you are using aggregates wrong. Aggregates are intended to be used as an atomic unit. An aggregate gets loaded as one thing and it gets persisted by one thing. No matter what you do, this is going to be slow. A domain like this should be modelled as two separate aggregates.

Of course, even with smaller aggregates, this comes at a cost. If the cost matters and inside your application you know a better behaviour, you can and should implement that in a custom method. For example you could have an addEntry method, that performs just the single insert for the example you gave in the question.

For the implicit question: Why is Spring Data doing this thing? The answer is "simplicity". In order to avoid this basic approach one would need to keep track what actually changes in an aggregate. This is basically the approach JPA chose. It means you'll need to keep a reference to the aggregate. You'll have to deal with the cases when one entity is represented by multiple instances in your application. These are the things that make JPA so complex. Spring Data JDBC takes a different approach. It basically goes: "I have no idea what state the database is in right now, but once I'm done with the persist operation it has to match the state of the aggregate inside the application"

There are plans and ideas to improve the behaviour. We are currently introducing quite some batch operations, which have the potential to speed up things. There is also a ticket to do a "delete/upsert" operation instead, which should perform better. But it will still touch all rows.

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