JPA中的最大打开游标超出了异常(使用createNativeQuery删除记录)

时间:2018-06-27 11:55:19

标签: java multithreading oracle jpa

我遇到错误(发生ORA-01000的次数比其他错误多)-

  1. ORA-01000:已超出打开游标的最大数量
  2. ORA-00604:递归SQL级别1发生错误
  3. [ne.jdbc.spi.SqlExceptionHelper]-不再需要从套接字读取数据

我将尝试解释我正在运行的代码方案。

  1. 服务调用DAO层以删除我通过主记录的记录 键来查找和删除表格。

    @Transactional(value = "txManagerResult")
    public void deleteCalculatedLkmsEntities(final List<Long> chkdLkmsIds) {
        this.daoResult. deleteCalculatedLkmsEntitiesEnhanced(chkdLkmsIds);
    }
    
  2. DAO方法可从4个表(具有父级和子级)中删除记录 数据上的关系,但表上未维护此关系 (即没有外键关系)。

    private void deleteCalculatedLkmsEntitiesEnhanced(final List<Long> chkdLkmsIds) {
    
         // Order of the delete is must be maintained as below 
    
         // this will delete  around 100000 rows for 1000 primary key of parent table
         this.deleteEntitiesByPrimaryKeyList("delete from Child_Table_4 where CHKD_PRODUCT_OFFERING_ID in ( "
                       + " select ID from Child_Table_2 where CHKD_LKMS_ID in ( "
                       + "select ID from Parent_Table_1 where id in (:pid) "
                       + ") )"
                       , "pid",
                       chkdLkmsIds);
    
    // this will delete  around 100000 rows for 1000 primary key of parent table
         this.deleteEntitiesByPrimaryKeyList("delete from Child_Table_3 where CHKD_PRODUCT_OFFERING_ID in ( "
                       + " select ID from Child_Table_2 where CHKD_LKMS_ID in ( "
                       + "select ID from Parent_Table_1 where id in (:pid) "
                       + ") )"
                       , "pid",
                       chkdLkmsIds);
    
    // this will delete  around 300000 rows for 1000 primary key of parent table
         this.deleteEntitiesByPrimaryKeyList("delete from Child_Table_2 where CHKD_LKMS_ID in ( "
                       + "select ID from Parent_Table_1 where id in (:pid) )"
                       , "pid",
                       chkdLkmsIds);
    
         // this will delete around 1000 rows
         this.deleteEntitiesByPrimaryKeyList("delete from Parent_Table_1 where ID in (:pid)"
                       , "pid",
                       chkdLkmsIds);
    
    } 
    private void deleteEntitiesByPrimaryKeyListFromDB(final String query, final String parameter,
                final List<Long> idsToDelete) {
         this.entityManager.createNativeQuery(query)
         .setParameter(parameter, idsToDelete).executeUpdate();
       }
    

由4个由ForkJoinPool管理的并行线程调用该服务方法。

错误不会在应用程序启动后立即出现,而是在执行代码10个小时后开始出现。上面的方法使线程以循环方式保持运行(删除记录)。运行此过程以完成900万条记录的执行。

请帮助。

1 个答案:

答案 0 :(得分:0)

查看所有评论。由于大量并行调用,它可能会发生。假设em.createNativeQuery()正在正确处理数据库资源生命周期。如果使用的是oracle DB,则最大打开游标有限制。您可以在数据库级别增加打开的游标的最大数目以解决此问题。