Java 处理异常时,Spring批处理跳过策略卡在无限循环中

Java 处理异常时,Spring批处理跳过策略卡在无限循环中,java,sql,spring,oracle,jdbc,Java,Sql,Spring,Oracle,Jdbc,Spring批处理作业,该作业使用自定义跳过策略来处理在将所有记录加载到数据库后引发的异常。我的脚步看起来像 @Bean public Step trialBalanceLoadStep(JdbcBatchItemWriter<TrialBalance> trialBalanceWriter) throws ParseException { return stepBuilderFactory.get("trialBalanceLoadStep

Spring批处理作业,该作业使用自定义跳过策略来处理在将所有记录加载到数据库后引发的异常。我的脚步看起来像

    @Bean
    public Step trialBalanceLoadStep(JdbcBatchItemWriter<TrialBalance> trialBalanceWriter) throws ParseException {
        return stepBuilderFactory.get("trialBalanceLoadStep")
                .<TrialBalance, TrialBalance> chunk(1000)
                .reader(trialBalanceReader())
                .writer(trialBalanceWriter)
                .faultTolerant()
                .skipPolicy(new CustomSkipPolicy())
                .build();
    }
我处理异常只是为了测试目的。但我看到的是org.springframework.dao.DuplicateKeyException被抛出

此文件中没有重复项。请不要问。没有。我已经删除了整个文件。它们不存在。事实上,整个记录计数正在加载到数据库中。即使在该作业失败后,如果对表进行计数,也会得到文件的整个记录计数。因此,在加载所有记录后将引发此异常

只有当此表上存在特定索引时,才会发生这种情况。创建索引是因为我们有一个查询此表的实时进程,并且使用索引查询运行时间要快得多。所以我们想保留索引。但是,索引(可能是也可能不是导致问题的原因)正在抛出异常,现在批处理加载作业将不会运行

因此,我试图通过创建这个CustomSkippPolicy类来处理抛出的异常,但当我这样做时,它会停留在一个无限循环中(如果我在return语句之前放一个println,它会一直输出)

编辑 添加架构和trialBalanceWriter

当我运行一个描述

Name                           Null?    Type         
------------------------------ -------- ------------ 
BAT_PROC_DT                    NOT NULL DATE         
ETL_TS                                  TIMESTAMP(6) 
PROC_APPL_CD                            VARCHAR2(3)  
FIRM_BNK_ID                    NOT NULL VARCHAR2(4)  
ACCT_NB                        NOT NULL VARCHAR2(15) 
ACCT_TYPE_CD                            VARCHAR2(2)  
CUST_ACCT_OWNR_SHRT_NM                  VARCHAR2(20) 
ACCT_CURR_BAL_AM                        NUMBER(15,2) 
ACCT_PROD_GP_CD                         VARCHAR2(3)  
SO_SCRTY_NB_ID                          NUMBER(9)    
ACCT_BR_ID                              NUMBER(7)    
ACCT_OPN_DT                             DATE         
CHK_OR_SV_LFCYC_STS_CD                  VARCHAR2(2)  
ACC_ROLL_12MO_OD_INSTN_CN               NUMBER(3)    
CHK_OR_SVACC_RCNCL_TXN_TYPE_CD          VARCHAR2(1)  
ACC_SRVC_FEE_BILL_SYS_CD                CHAR(1)      
CHK_OR_SVACC_LOB_CD                     VARCHAR2(3)  
CHK_OR_SVACC_LOB_OWNR_CD                VARCHAR2(2)  
CHK_ACCT_PSTV_PAY_IN                    CHAR(1)      
CHK_OR_SVACC_OD_TXN_PYMT_CD             CHAR(1)      
ACC_LAST_DAY_TOT_DEP_AM                 NUMBER(13)   
PRNT_ACCT_NB                            NUMBER(15)   
CARD_ACCT_NB                            NUMBER(17)   
CHK_OR_SVACC_OD_AM                      NUMBER(11)   
ACC_MO_TO_DT_OD_INSTN_DAY_CN            NUMBER(3)    
CHK_OR_SVACC_OD_PRTC_CD                 CHAR(1)      
CHK_OR_SVACC_OD_LAST_2PRTC_CD           CHAR(1)      
CHK_OR_SVACC_OD_LAST_3PRTC_CD           CHAR(1)      
CHK_OR_SVACC_LAST_MNTR_ACTV_DT          DATE         
CHK_OR_SVACC_LAST_DEP_DT                DATE         
CHK_OR_SVACC_MOST_RCNT_OD_DT            DATE         
STOP_PYMT_CD                            CHAR(1)      
CNTPR_TYPE_CD                           VARCHAR2(2)  
RISK_AVD_CD                             CHAR(1)      
RET_MAIL_STS_CD                         CHAR(1)      
AUTM_CLR_HS_IN                          CHAR(1)      
FED_TAX_WHLD_CD                         VARCHAR2(2)  
LAST_OD_DSPN_CD                         NUMBER(1)    
ACC_CAL_MO_TO_DT_ALB_AM                 NUMBER(15,2) 
ACC_MO_TO_DT_OD_INSTN_CN                NUMBER(3)    
ACCT_MO_TO_DT_RET_ITEM_CN               NUMBER(3)    
ACCT_MO_TO_DT_NSF_ITEM_CN               NUMBER(3)    
ACCT_CTL_DISB_CD                        CHAR(1)      
ACC_ROLL_12MO_AVG_COLL_BAL_AM           NUMBER(13)   
ACC_ROLL_12MO_OD_INSTN_DAY_CN           NUMBER(3)    
ACCT_ROLL_12MO_NSF_ITEM_CN              NUMBER(3)    
ACC_12MO_NSF_PTNL_RET_ITEM_CN           NUMBER(5)    
ACCT_ROLL_12MO_RET_ITEM_CN              NUMBER(3)    
CHK_OR_SVACC_OPN_DT                     DATE         
ACC_OD_PRTC_AVAL_FUND_AM                NUMBER(15,2) 
DBCD_LAST_CHRG_DT                       DATE         
CHK_OR_SVACC_PRC_RGN_NB                 NUMBER(5)    
DEP_ACCT_FUND_PRPS_CD                   CHAR(1)      
CHK_OR_SVACC_OD_PRTC_PROD_CD            NUMBER(1)    
UNVS_PROD_CAT_CD                        VARCHAR2(4)  
SGNTR_RVW_THLD_AM                       NUMBER(9)    
TXN_MIN_SGNTR_CN                        NUMBER(1)    
ACH_DEP_LTST_DT                         DATE         
TELR_BLK_TXN_TYPE_CD                    CHAR(1)      
PRVT_BNK_REL_CD                         CHAR(1)      
CHK_OR_SV_AVAL_BAL_AM                   NUMBER(15,2) 
CHK_OR_SVACC_COLL_BAL_AM                NUMBER(15,2) 
DDA_PNDG_HARD_HOLD_AM                   NUMBER(15,2) 
RCNT_CYC_CR_AM                          NUMBER(15,2) 
RCNT_CYC_DR_AM                          NUMBER(15,2) 
ACCT_PRPS_CD                            VARCHAR2(2)  
PYMT_FUND_SRC_CD                        VARCHAR2(2)  
CHK_ACCT_CHK_ENCST_CD                   CHAR(1)      
ACCT_ROLL_12MO_ALB_AM                   NUMBER(13)   
ACCT_ACTV_CD                            CHAR(1)      
OV_DRFT_PRTC_ACCT_NB                    NUMBER(15)   
OV_DRFT_PRTC_ACCT_LNK_DT                DATE         
ACCT_CLSE_DT                            DATE         
STOP_NOTE_IN                            CHAR(1)      
RCNT_CYC_CR_ITEM_CN                     NUMBER(7)    
RCNT_CYC_DR_ITEM_CN                     NUMBER(7)    
ADDL_WDRW_FEE_WVE_IN                    CHAR(1)      
ACCT_CLSE_SPRS_CD                       CHAR(1)      
ACCT_RCNT_ACTV_DT                       DATE         
GL_CC_NB                                NUMBER(7)    
ACCT_LAST_CNTC_DT                       DATE         
CHK_OR_SVACC_OD_DAY_CN                  NUMBER(3)    
UNVS_PROD_FAM_CD                        VARCHAR2(4)  
trialBalanceWriter如下所示

    @Bean
    public JdbcBatchItemWriter<TrialBalance> trialBalanceWriter(final DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<TrialBalance>()
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql(Constants.trialBalanceInsertStatement)
                .assertUpdates(false)
                .dataSource(dataSource)
                .build();
    }
@Bean
公共JdbcBatchItemWriter trialBalanceWriter(最终数据源数据源){
返回新的JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(新的BeanPropertyItemSqlParameterSourceProvider())
.sql(Constants.trialBalanceInsertStatement)
.资产更新(错误)
.dataSource(数据源)
.build();
}

主键列有问题,要么包含空值,要么其值(pk列的值,而不是记录本身)不唯一


之所以在添加所有记录后抛出它,很可能是因为此时事务已提交。

这与其说是答案,不如说是注释。请不要只为一些想法创建答案,如果文件中只有10条记录,就会出现这种情况。我很明显地看到没有主键重复。即使我要用一个重复的主键创建一个列,也会抛出这个异常,而不是在加载的记录末尾。它是在提交了那批记录之后抛出的。@BrianCode您介意添加架构,甚至是trialBalanceWriter吗?@Stefan刚刚用这两个进行了编辑。您想要表的模式吗?那是我贴的
    @Bean
    public JdbcBatchItemWriter<TrialBalance> trialBalanceWriter(final DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<TrialBalance>()
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql(Constants.trialBalanceInsertStatement)
                .assertUpdates(false)
                .dataSource(dataSource)
                .build();
    }