当前位置: 首页 > 知识库问答 >
问题:

Spring数据JPA批量插入非常慢

姚向晨
2023-03-14

我正在尝试读取包含700K条记录的Excel文件,并将这些记录批量插入MySQL数据库表中。

请注意,Excel解析速度很快,我可以在50秒左右的时间内将实体对象放入ArrayList中。

我使用Spring Boot和Spring数据JPA。

下面是我的部分应用程序。属性文件

hibernate.jdbc.batch_size=1000
spring.jpa.hibernate.use-new-id-generator-mappings=true

以及我的部分实体类

@Entity
@Table(name = "WHT_APPS", schema = "TEST")
public class WHTApps {

    @Id
    @TableGenerator(name = "whtAppsGen", table = "ID_GEN", pkColumnName = "GEN_KEY", valueColumnName = "GEN_VAL")
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "whtAppsGen")
    private Long id;

    @Column(name = "VENDOR_CODE")
    private int vendorCode;
    .
    .
    .
    .

以下是我的 DAO

@Repository
@Transactional
public class JapanWHTDaoImpl implements JapanWHTDao {

    @Autowired
    JapanWHTAppsRepository appsRepo;

    @Override
    public void storeApps(List<WHTApps> whtAppsList) {
        appsRepo.save(whtAppsList);

    }

下面是存储库类:

@Transactional
public interface JapanWHTAppsRepository extends JpaRepository<WHTApps, Long> {

}

有人能告诉我我在这里做了什么不正确的事情吗?

编辑:

进程未完成并最终抛出错误:-

2017-08-15 15:15:24.516  WARN 14710 --- [tp1413491716-17] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 08S01
2017-08-15 15:15:24.516 ERROR 14710 --- [tp1413491716-17] o.h.engine.jdbc.spi.SqlExceptionHelper   : Communications link failure

The last packet successfully received from the server was 107,472 milliseconds ago.  The last packet sent successfully to the server was 107,472 milliseconds ago.
2017-08-15 15:15:24.518  INFO 14710 --- [tp1413491716-17] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements
2017-08-15 15:15:24.525  WARN 14710 --- [tp1413491716-17] c.m.v.c3p0.impl.DefaultConnectionTester  : SQL State '08007' of Exception tested by statusOnException() implies that the database is invalid, and the pool should refill itself with fresh Connections.

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_131]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_131]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_131]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.43.jar:5.1.43]
    .
    .
    .
    .
    2017-08-15 15:15:24.526  WARN 14710 --- [tp1413491716-17] c.m.v2.c3p0.impl.NewPooledConnection     : [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
2017-08-15 15:15:24.527  WARN 14710 --- [tp1413491716-17] c.m.v2.c3p0.impl.NewPooledConnection     : [c3p0] Another error has occurred [ com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown. ] which will not be reported to listeners!

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_131]

谢谢

共有1个答案

乌和畅
2023-03-14

我还要指出一点。问题可能不仅在于hibernate,还在于DB。

当您在一个事务中插入700k个对象时,它可以存储在DB的回滚段中,等待事务提交。

如果可能的话,将逻辑分割成中间提交。

从主列表创建1k大小的子列表,保存子列表并在每次保存子列表后提交。

 类似资料:
  • 在我的spring boot应用程序中,我试图进行批插入以提高写入性能。问题是,我定期获得重复数据,对于这些数据,我的表上有一些唯一的约束。在进行串行插入时,我只捕获DataIntegrityException并忽略它们。但在执行批插入时,即使一次插入失败,也不会保存整个批。我希望hibernate仍然保存不会抛出错误的记录。我正在使用存储库。saveAll()用于插入,我的数据库是Mysql

  • 我使用Spring Data、Spring Boot和Hibernate作为JPA提供程序,我想提高批量插入的性能。 我引用这个链接来使用批处理: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch15.html 这是我的代码和应用程序。插入分批实验的属性。 我的服务: 与批处理相关的部分application.properti

  • 我将Spring Boot与Hibernate结合使用,为一个简单的web应用程序创建RESTful API,在该应用程序中,我读取一个。csv文件,并将每一行插入到mysql数据库表中。我能够成功地做到这一点,但它需要很长的时间为任何大的csv文件。我明白最好对insert语句进行批处理,以减少事务的数量,但我不认为我用当前的代码实现了这一点。这是我目前正在做的(工作,但非常缓慢): csvup

  • 我正在研究一个实时用例,需要使用spring boot JPA将一批消息加载到SQL server表中,将所有模型对象添加到列表中,并对批加载<code>存储库进行此操作。saveAll(list)。由于性能原因,我无法逐个记录插入。我正在寻找以下选项。 是否有任何方法可以读取导致错误的消息并继续将其他记录插入表中。我必须将此错误消息存储在某个地方,并且不应传递给下游应用程序。

  • 问题内容: 这是我在阅读有关jpa批量插入的几个主题之后创建的简单示例,我有2个持久对象User和Site。一个用户可以拥有多个站点,因此我们在这里有一对多的关系。假设我要创建用户并将多个站点创建/链接到用户帐户。考虑到我愿意为Site对象使用批量插入,代码如下所示。 但是,当我运行此代码时(我将hibernate方式用作jpa实现提供程序),我看到以下sql输出: 所以,我的意思是“真实的”批量

  • 问题内容: 我有一个测试用例,需要将100‘000个实体实例持久存储到数据库中。我当前使用的代码可以做到这一点,但是要花40秒才能将所有数据持久保存在数据库中。从大小约为15 MB的JSON文件中读取数据。 现在,在另一个项目之前,我已经在自定义存储库中实现了批量插入方法。但是,在那种情况下,我要保留许多顶级实体,而只有少数嵌套实体。 在我目前的情况下,我有5个实体,其中包含约30个实体的列表。其