【问题标题】:handle sql exception for large data insert处理大数据插入的sql异常
【发布时间】:2022-01-17 07:24:38
【问题描述】:

我有一个 Spring 2.5 应用程序,它需要一个大 (275K) 文件并对其进行解析。然后将每条记录插入到 Postgres 数据库中。有一个唯一的列(不是primaryKey/@Id)将退出尝试的记录插入。这会导致 DataContraintViolationException,这看起来很自然。

我遇到的问题是这会杀死进程。有没有一种好方法可以继续处理整个文件,只记录异常并移动到下一条记录以进行插入?我尝试将 respository.save(record) 包装在 try/catch 中,但它仍然会通过事务回滚终止进程。

【问题讨论】:

    标签: spring-data-jpa


    【解决方案1】:

    ConstraintViolationException 将被包裹在 PersistenceException 中,Hibernate 将 generally 标记事务以进行回滚 - 即使如果异常被注册为不会在 Spring 事务处理中导致回滚水平,例如通过@Transactional(noRollbackFor = PersistenceException.class)

    因此需要有不同的解决方案。一些想法:

    1. 明确查看对应的行是否已经存在(每个项目一个额外的选择)
    2. 尝试在专用事务中的每个插入(例如,使用 @Transactional(propagation = Propagation.REQUIRES_NEW) 注释相应的服务方法(每个项目一个附加事务)
    3. 在自定义 DB 语句中处理约束冲突(例如 ON CONFLICT DO NOTHING / DB 提供的其他“upsert”/“merge”行为)

    第一个和第二个选项应该提供一些并行化的潜力,因为选择/插入可以彼此独立发出,并且不需要等待不相关的数据库往返。

    第 3 个选项可能是最快的,因为它不需要选择,最少的数据库往返,并且可以批处理语句;但是它可能还需要最多的自定义设置:Spring JPA bulk upserts is slow (1,000 entities took 20 seconds)(报告实际插入的数量甚至是哪些实体甚至可能会增加复杂性:How can I get the INSERTED and UPDATED rows for an UPSERT operation in postgres

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多