【问题标题】:Spring boot hibernate/jpa batch update not working春季启动休眠/ jpa批量更新不起作用
【发布时间】:2021-10-02 13:47:23
【问题描述】:

应用程序属性

spring.datasource.url=jdbc:as400://localhost/

spring.jpa.properties.hibernate.jdbc.batch_size = 30
spring.jpa.properties.hibernate.order_updates = true
spring.jpa.properties.hibernate.batch_versioned_data = true

实体 -

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity(name = "entity")
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false);

   @ManyToOne
   @JoinColumn(name = "HDR_ID", referencedColumnName = "HDR_ID")
   @JsonIgnore
   private Header header;

   @ManyToOne
   @JoinColumn(name = "STS_ID", referencedColumnName = "STS_ID")
   private Status status;
}

服务-

this.myRepository.saveAll(MyEntitylist);

Gradle -

    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
    implementation 'org.springframework.boot:spring-boot-starter-web'

我正在使用 Spring Boot 2.3.5.RELEASE。 我正在尝试使用休眠批处理更新批量记录,但它似乎不起作用。我没有收到任何错误,记录在数据库中更新没有任何问题,但没有性能改进。实际上,无论有没有 Hibernate 批处理,我都找不到任何区别。我检查了日志,他们的查询记录了每条记录,例如,如果我尝试保存 1000 条记录,那么日志中将有 1000 个更新查询。

我预计批处理后的更新查询会减少,具体取决于批处理大小,并且与没有批处理查询相比,它应该花费更少的时间。

我的代码中是否存在任何配置问题? jdbc:as400 是否有类似 reWriteBatchedInserts 的选项来显示多行插入查询?

【问题讨论】:

  • 您的帖子并没有真正说明您要解决的问题是什么。您是否收到错误消息?您的 MyEntity 类中似乎缺少 Id 成员。
  • 嗨@crig,我在帖子中添加了更多细节。我正在尝试使用批处理来提高性能,但它似乎不起作用,而且我也没有收到任何错误,

标签: java spring-boot hibernate jpa


【解决方案1】:

如果您使用身份标识符生成器,​​Hibernate 会在 JDBC 级别透明地禁用插入批处理。

https://docs.jboss.org/hibernate/core/4.3/devguide/en-US/html_single/#batch

【讨论】:

    【解决方案2】:

    仅仅因为您在数据库日志中看到查询并不意味着批处理不起作用。 JDBC 批处理是一种协议级别的优化,依赖于驱动程序的支持。 JDBC 驱动程序可以通过发出单独的语句来实现这一点。优化通常来自重用相同的服务器句柄并批量发送值。不过,对于 1000 个元素来说,增益可能太小了。如果您没有看到任何改进,您应该咨询您的驱动程序供应商。您没有显示记录了哪些类型的查询,您确定在更新语句之间没有执行其他语句吗?

    【讨论】:

    • 有什么方法可以检查批处理是否正常工作?我正在使用 com.ibm.as400.access.AS400JDBCDriver
    • 你可以调试到org.hibernate.engine.jdbc.batch.internal.BatchingBatch#addToBatch看是否使用了JDBC批处理API。
    • 我已经调试了 addToBatch 方法,它按预期工作,它正在检查 batchSize,如果 batchPosition == batchSize,它正在执行 SQL 查询。也许我需要使用大型数据集进行测试以检查性能,并且需要启用调试日志以在日志文件中添加批处理相关日志谢谢
    • 我发现批量更新对性能的影响并不大。在某种程度上,您仍在更新单个记录,这基本上必须一次完成。如果可以批量发送数据,您可能会节省一些来回时间,但通常每个单独的 UPDATE stmt 仍然必须单独运行。 *我认为。
    • 如果您可以将其表述为单个 DML 更新语句,那么显然它总是会表现得更好,但有时用这种方式处理是不可能的,或者只是更容易处理。
    猜你喜欢
    • 2020-05-17
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 2020-10-21
    • 1970-01-01
    • 2014-06-14
    相关资源
    最近更新 更多