【发布时间】:2020-11-09 23:45:20
【问题描述】:
使用自定义跳过策略处理在所有记录加载到数据库后引发的异常的 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();
}
我的 CustomSkipPolicy 类是...
public class CustomSkipPolicy implements SkipPolicy {
@Override
public boolean shouldSkip(Throwable throwable, int i) {
if (throwable instanceof Exception) {
return true;
}
return false;
}
}
我处理异常只是为了测试目的。但是我看到的是 org.springframework.dao.DuplicateKeyException 被抛出。
此文件中没有重复项。请不要问。没有。我已经删除了整个文件。它们不存在。事实上,整个记录计数正在加载到数据库中。即使在这项工作失败后,如果我对表进行计数,我也会得到文件的整个记录数。所以这个异常是在所有记录都被加载之后抛出的。
仅当此表上存在特定索引时才会发生这种情况。创建索引是因为我们有一个实时进程查询该表,并且索引的查询运行时间明显更快。所以我们想保留索引。但同样,索引(可能会也可能不会导致问题)正在引发异常,现在我们的批量加载作业将无法运行。
所以我试图通过创建这个 CustomSkipPolicy 类来处理抛出的这个异常,但是当我这样做时它会处于无限循环中(如果我在我的 return 语句之前放置一个 println,它只会继续输出)
编辑 添加 schema 和 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();
}
【问题讨论】:
标签: java sql spring oracle jdbc