【问题标题】:Efficient way to bulk load and update using spring data jpa(hibernate)使用spring data jpa(hibernate)批量加载和更新的有效方法
【发布时间】:2020-04-11 06:27:07
【问题描述】:

我正在使用 spring boot(2.2.1) 和 spring data jpa。

我的应用程序运行了一项计划服务,我必须在其中读取多家公司的数百万客户数据(带有分页)。 在做了一些操作之后,我必须为这些用户更新一个状态列。 要更新状态,我正在使用本机查询(使用 @Query 注释和 nativeQuery=true)。

public void scheduledTask() {
  List<Integer> companies = getCompanies();
  for each company:
      1. get x customers
      2. do some operation

    3. repeat step 1 -> 2 for all customers in a company 
       and then update the read status for the customers
}

在处理一些客户记录后,如果出现任何异常,已处理记录的读取状态不会更新。 此外,如果处理了几百万条客户记录,hibernate entity manager 将被关闭。

在上述流程执行中,读取状态只有在处理完所有公司的所有客户后才会更新。

现在,我想知道是否有任何有效的方法来加载和更新客户的数据,以便在出现异常时我的读取状态更新不会丢失。

【问题讨论】:

  • 您不会在一次通话中读取一百万客户的记录。此外,您的伪代码不会显示您拥有的内容,您可以删除核心业务逻辑,但在没有看到您的代码的情况下,做出假设对任何人都无济于事。另外,你是如何安排你的方法的?

标签: hibernate spring-boot spring-data-jpa


【解决方案1】:

对此的最佳解决方案在很大程度上取决于“执行某些操作”的含义以及您必须处理的异常原因。 由于我们不知道这一点,我会坚持一些一般性建议。

  1. 为了使您的更改不被回滚,请将它们放在单独的事务中。

  2. 避免大量的小交易。每个事务都会强制数据库进行一些 I/O,这会降低性能。对大笔交易可能也会有一些问题。

  3. 避免使用 JPA 进行此类工作。 JPA 的优势在于 CRUD 操作,您可以在其中加载一个或几个实体,更改它们并将更改刷新到数据库中。 对于我们这里的大规模批处理操作,坚持使用 JDBC 和 SQL。 它的开销要少得多。

  4. 研究用于批处理操作的特殊工具,例如 Spring Batch。

  5. 关于异常:尽量避免它们。或者至少避免他们跨越您的交易边界。您可能会考虑重试策略,首先尝试一批客户,如果这批客户抛出异常,则一个一个地处理它们,这样只有导致异常的人不会通过该过程。

    李>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-11
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2016-07-21
    • 2019-07-20
    • 2016-05-22
    相关资源
    最近更新 更多