Java 处理异常时,Spring批处理跳过策略卡在无限循环中
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
@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();
}