Deferred Process Numbering Service Development
The deferred process numbering service must be developed by creating a Bxm bean, and the bean input argument must use bxm.deferred.data.IDeferredMainInfo.
The following figure shows the input and output of the deferred process numbering service. The numbering service input value passes the values of the deferred process main table.
The following table describes the column names of the input DTO.
| Column (physical name) | Column (logical name) | Type |
|---|---|---|
domainId |
Domain ID |
String |
deferredId |
Deferred process ID |
String |
trxCd |
Transaction code |
String |
bxmAppId |
BXM application ID |
String |
svcNm |
Service name |
String |
opNm |
Operation name |
String |
deferredNm |
Deferred process name |
String |
useYn |
Usage status |
String |
errStopYn |
Error stop status |
String |
errSkipYn |
Error SKIP status |
String |
nodeExecYn |
Execution status by node |
String |
startTypeCd |
Start type code |
String |
svcProcCd |
Service processing code |
String |
deferredTranCd |
Deferred process transaction code |
String |
execIntervalSec |
Execution interval (seconds) |
Integer |
delayIntervalSec |
Delay interval (seconds) |
Integer |
fetchCnt |
Number of records retrieved |
Integer |
parllExecCnt |
Parallel execution count |
Integer |
targetTableNm |
Target table name |
String |
dayTableYn |
Daily table status |
String |
targetColumnNm |
Target column name |
String |
targetStdDtNm |
Standard date name |
String |
tableReaderBeanNm |
Table reader bean name |
String |
tableNumberingUseYn |
Table numbering usage status |
String |
tableNumberingBxmAppId |
BXM application ID |
String |
tableNumberingBeanNm |
Table numbering bean name |
String |
errReprocCnt |
Number of reprocessings |
Integer |
reprocAbleErrCd |
Reprocessable error code |
String |
modifyUserId |
User ID |
String |
modifyOccurDttm |
Date of occurrence |
String |
The following example is a sample of deferred process numbering bean development.
@Override
public long callNumbering(IDeferredMainInfo in)
{
String bizDt;
// 1. Get the standard date.
bizDt = getStandardDate(in);
// 1.1 bizDt can be null. Consider another way to get bizDt
// or end by returning 0 as done here.
if ( !isValidBizDt(bizDt))
{
logger.error("Not valid bizDt : [{}]", bizDt);
return 0;
}
// 2. Check whether seq data to be processed currently exists
int seqCount = getSeqData(in, bizDt);
// 3. Check the initial loading of the Seq table and whether the previous date is closed
if (seqCount == 0)
{
insertSeqInitialData(in, bizDt);
checkBeforeEndYn(in);
}
// 4. Read the information to be numbered currently
DfrdSeq01IO numberingInfo = getNumberingInfo(in, bizDt);
DfrdSeq01IO afterNumberingSeqInfo;
// 2017-09-05
// 4.1 Defensive logic against sudden interruption
// If a sudden interruption occurs during numbering, BXM_LOG_TRX may be numbered,
// but BXM_DEFERRED_SEQ may not be updated.
// Get BXM_LOG_TRX MAX_SEQ and match it if it is different from seqCount
int maxSeq = getMaxSeq(in, bizDt);
if (numberingInfo.getLastProcLogSeq().intValue() != maxSeq)
{
numberingInfo.setLastProcLogSeq(maxSeq);
numberingInfo.setProcExecCnt(maxSeq);
numberingInfo.setDomainId(in.getDomainId());
updateNumbering(numberingInfo);
}
// 5. Execute numbering
BigDecimal beforeProcExecCnt = numberingInfo.getProcExecCnt();
try
{
afterNumberingSeqInfo = executeNumbering(in, numberingInfo, bizDt);
}
catch (IllegalStateException e)
{
executeErrorProcess(in, bizDt);
throw new IllegalStateException("Numbering Error Update.");
}
// 6. Update BXM_DEFERRED_SEQ
BigDecimal procExecCnt = afterNumberingSeqInfo.getProcExecCnt();
if (procExecCnt.compareTo(beforeProcExecCnt) != 0)
updateSeq(afterNumberingSeqInfo);
// 7. Error handling in case of duplicate LOG_SEQ (additional defensive logic)
checkDuplicateLogSeq(in, bizDt);
// 8. Return the last LogSeq
return afterNumberingSeqInfo.getLastProcLogSeq().intValue();
}
@Override
public long checkIncompletionDataCnt(IDeferredMainInfo in)
{
// logger.debug("checkIncompletionDataCnt : [{}]", in);
return 0;
}
@Override
public long checkIncompletionNumberingCnt(IDeferredMainInfo in)
{
// logger.debug("checkIncompletionNumberingCnt : [{}]", in);
return 0;
}
private void updateNumbering(DfrdSeq01IO in)
{
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
dfrdSeqDBIO.updateLastProcLogSeq01(in);
}
private int getMaxSeq(IDeferredMainInfo in, String bizDt)
{
if (bxmLogTrxDBIO == null)
bxmLogTrxDBIO = LApplicationContext.getBean(BxmLogTrxDBIO.class);
String day = NumberingUtil.getBizDay(bizDt);
int maxSeq = bxmLogTrxDBIO.getMaxSeq01(day, bizDt, in.getDomainId());
return maxSeq;
}
private String getStandardDate(IDeferredMainInfo in)
{
if (dfrdStatusDBIO == null)
dfrdStatusDBIO = LApplicationContext.getBean(DfrdStatusDBIO.class);
DfrdStatus01IO dfrdStatus01IO = new DfrdStatus01IO();
dfrdStatus01IO.setDeferredId(in.getDeferredId());
dfrdStatus01IO.setDomainId(in.getDomainId());
String bizDt = dfrdStatusDBIO.selectDfrdStatus01(dfrdStatus01IO);
return bizDt;
}
private boolean isValidBizDt(String bizDt)
{
return !(StringUtils.isEmpty(bizDt)) && (bizDt.length() == 8);
}
private int getSeqData(IDeferredMainInfo in, String bizDt)
{
int seqCount;
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
DfrdSeq01IO dfrdSeq01IO = new DfrdSeq01IO();
dfrdSeq01IO.setDeferredId(in.getDeferredId());
dfrdSeq01IO.setBizDt(bizDt);
dfrdSeq01IO.setDomainId(in.getDomainId());
seqCount = dfrdSeqDBIO.selectDfrdSeqNotProcEnd01(dfrdSeq01IO);
return seqCount;
}
private void insertSeqInitialData(IDeferredMainInfo in, String bizDt)
{
DfrdSeq01IO dfrdSeqInitialData = new DfrdSeq01IO();
dfrdSeqInitialData.setDeferredId(in.getDeferredId());
dfrdSeqInitialData.setBizDt(bizDt);
dfrdSeqInitialData.setNodeNo(0);
dfrdSeqInitialData.setFirstProcStartDttm(NumberingUtil.getCurrentTime());
dfrdSeqInitialData.setLastProcLogSeq(0);
dfrdSeqInitialData.setProcExecCnt(0);
dfrdSeqInitialData.setProcEndYn("N");
dfrdSeqInitialData.setProcErrYn("N");
dfrdSeqInitialData.setDomainId(in.getDomainId());
try
{
dfrdSeqDBIO.insertDfrdSeq01(dfrdSeqInitialData);
}
catch (DasDuplicateKeyException e)
{
logger.error("deferredId [{}], baseDt [{}] is already exist. ", in.getDeferredId(), bizDt);
}
}
private void checkBeforeEndYn(IDeferredMainInfo in)
{
DfrdWork01IO beforeDayDfrdWork01IO = new DfrdWork01IO();
beforeDayDfrdWork01IO.setBizDt(NumberingUtil.getBeforeDay());
beforeDayDfrdWork01IO.setDeferredId(in.getDeferredId());
beforeDayDfrdWork01IO.setDomainId(in.getDomainId());
if (dfrdWorkDBIO == null)
dfrdWorkDBIO = LApplicationContext.getBean(DfrdWorkDBIO.class);
int dfrdEndWorkCount = dfrdWorkDBIO.selectDfrdWorkAboutWorkEnd01(beforeDayDfrdWork01IO);
if (dfrdEndWorkCount != 0)
{
DfrdSeq01IO updateDfrdSeqEndYn = new DfrdSeq01IO();
updateDfrdSeqEndYn.setBizDt(NumberingUtil.getBeforeDay());
updateDfrdSeqEndYn.setDeferredId(in.getDeferredId());
updateDfrdSeqEndYn.setProcEndYn("Y");
updateDfrdSeqEndYn.setLastProcEndDttm(NumberingUtil.getCurrentTime());
updateDfrdSeqEndYn.setDomainId(in.getDomainId());
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
dfrdSeqDBIO.updateDfrdSeqEndYn01(updateDfrdSeqEndYn);
}
}
private DfrdSeq01IO getNumberingInfo(IDeferredMainInfo in, String bizDt)
{
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
DfrdSeq01IO selectDfrdSeq01IO = new DfrdSeq01IO();
selectDfrdSeq01IO.setDeferredId(in.getDeferredId());
selectDfrdSeq01IO.setBizDt(bizDt);
selectDfrdSeq01IO.setDomainId(in.getDomainId());
DfrdSeq01IO out = dfrdSeqDBIO.selectDfrdSeq01(selectDfrdSeq01IO);
return out;
}
private DfrdSeq01IO executeNumbering(IDeferredMainInfo deferredMainInfo, DfrdSeq01IO in, String bizDt)
{
DfrdSeq01IO out = new DfrdSeq01IO();
out.setCurrProcStartDttm(NumberingUtil.getCurrentTime());
String day = NumberingUtil.getBizDay(bizDt);
BigDecimal startSeqNo, endSeqNo, maxSeqNo;
int processedNumberingCount = 0;
int sqlResult;
startSeqNo = in.getLastProcLogSeq();
maxSeqNo = in.getLastProcLogSeq();
if (bxmLogTrxDBIO == null)
bxmLogTrxDBIO = LApplicationContext.getBean(BxmLogTrxDBIO.class);
List<BxmLogTrx01IO> list = bxmLogTrxDBIO.selectListLogTrx01(day, bizDt, deferredMainInfo.getDomainId());
for (BxmLogTrx01IO bxmLogTrx01IO : list)
{
maxSeqNo = maxSeqNo.add(BigDecimal.ONE);
bxmLogTrx01IO.setLogSeq(maxSeqNo);
bxmLogTrx01IO.setDay(day);
bxmLogTrx01IO.setDomainId(deferredMainInfo.getDomainId());
sqlResult = bxmLogTrxDBIO.updateDfrdInput01(bxmLogTrx01IO);
if(sqlResult == 0)
{
logger.error("deferredId : [{}] Numbering Update Error. guid : [{}], curSeq : [{}]"
, new Object[]{in.getDeferredId(), bxmLogTrx01IO.getGuid(), maxSeqNo});
throw new IllegalStateException("Dfrd AcctgLog Numbering Update Error.");
}
else
{
processedNumberingCount += 1;
}
}
endSeqNo = maxSeqNo;
logger.debug("deferredId : [{}] Dfrd AcctgLog Numering Update startSeq [{}] ~ endSeq[{}]"
, new Object[]{in.getDeferredId(), startSeqNo, endSeqNo});
out.setDeferredId(in.getDeferredId());
out.setBizDt(bizDt);
out.setLastProcLogSeq(maxSeqNo);
out.setProcExecCnt(in.getProcExecCnt().intValue()
+ processedNumberingCount);
out.setNodeNo(in.getNodeNo());
out.setDomainId(deferredMainInfo.getDomainId());
return out;
}
private void executeErrorProcess(IDeferredMainInfo in, String bizDt)
{
DfrdSeq01IO dfrdSeq01IO = new DfrdSeq01IO();
dfrdSeq01IO.setDeferredId(in.getDeferredId());
dfrdSeq01IO.setCurrProcStartDttm(NumberingUtil.getCurrentTime());
dfrdSeq01IO.setBizDt(bizDt);
dfrdSeq01IO.setDomainId(in.getDomainId());
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
dfrdSeqDBIO.updateDfrdSeqErr01(dfrdSeq01IO);
}
private void updateSeq(DfrdSeq01IO in)
{
if (dfrdSeqDBIO == null)
dfrdSeqDBIO = LApplicationContext.getBean(DfrdSeqDBIO.class);
dfrdSeqDBIO.updateDfrdSeqLastest01(in);
}
private void checkDuplicateLogSeq(IDeferredMainInfo deferredMainInfo, String bizDt)
{
if (bxmLogTrxDBIO == null)
bxmLogTrxDBIO = LApplicationContext.getBean(BxmLogTrxDBIO.class);
String day = NumberingUtil.getBizDay(bizDt);
List<Integer> result = bxmLogTrxDBIO.selectListLogTrx03(day, deferredMainInfo.getDomainId());
if (result.size() != 0)
{
logger.error("LOG_SEQ not duplicate");
for (Integer i : result)
{
logger.error("duplicate log_seq : [{}]", i);
}
throw new IllegalStateException("LOG_SEQ not duplicate");
}
}