후행 처리 넘버링 서비스 개발

후행 처리 넘버링 서비스는 Bxm Bean 을 개발하여야 하며, Bean 입력 아규먼트는 bxm.deferred.data.IDeferredMainInfo 을 사용하여야 한다.

아래의 그림은 후행 처리 넘버링 서비스 입출력을 나타낸다. 넘버링 서비스 입력 값은 후행 처리 메인 테이블의 값을 전달해준다.

후행 처리 넘버링 서비스 입출력
Figure 1. 후행 처리 넘버링 서비스 입출력

아래 표는 입력 DTO 의 컬럼 명에 대해 설명한 것이다.

컬럼(물리 명) 컬럼(논리 명) 타입

domainId

도메인 ID

String

deferredId

후행 처리 ID

String

trxCd

거래코드

String

bxmAppId

BXM어플리케이션ID

String

svcNm

서비스 명

String

opNm

오퍼레이션 명

String

deferredNm

후행 처리 명

String

useYn

사용여부

String

errStopYn

에러중지여부

String

errSkipYn

에러SKIP여부

String

nodeExecYn

노드별실행여부

String

startTypeCd

시작유형코드

String

svcProcCd

서비스처리코드

String

deferredTranCd

후행처리트랜잭션코드

String

execIntervalSec

실행주기 초

Integer

delayIntervalSec

지연주기 초

Integer

fetchCnt

조회 건수

Integer

parllExecCnt

병렬실행 수

Integer

targetTableNm

대상테이블 명

String

dayTableYn

일별테이블여부

String

targetColumnNm

대상컬럼 명

String

targetStdDtNm

기준일자 명

String

tableReaderBeanNm

테이블리더빈 명

String

tableNumberingUseYn

테이블채번사용여부

String

tableNumberingBxmAppId

BXM어플리케이션ID

String

tableNumberingBeanNm

테이블채번빈 명

String

errReprocCnt

재처리횟수

Integer

reprocAbleErrCd

재처리가능에러코드

String

modifyUserId

사용자ID

String

modifyOccurDttm

발생 일시

String

아래의 예는 후행 처리 넘버링 빈 개발 샘플이다.

    @Override
    public long callNumbering(IDeferredMainInfo in)
    {
        String bizDt;

        // 1. 기준일자를 가져옴.
        bizDt = getStandardDate(in);

        // 1.1 bizDt 가 null 일 있음. bizDt를 가져오는 다른 방안을 강구하거나
        //      여기서처럼 return 0 하고 끝내던가
        if ( !isValidBizDt(bizDt))
        {
            logger.error("Not valid bizDt : [{}]", bizDt);
            return 0;
        }


        // 2. 현재 처리할 seq 데이터가 존재하는지 확인
        int seqCount = getSeqData(in, bizDt);


        // 3. Seq 테이블 초기 적재 및 전일자마감 여부 확인
        if (seqCount == 0)
        {
            insertSeqInitialData(in, bizDt);
            checkBeforeEndYn(in);
        }




        // 4. 현재 Numbering 할 정보 읽기
        DfrdSeq01IO numberingInfo = getNumberingInfo(in, bizDt);
        DfrdSeq01IO afterNumberingSeqInfo;

        // 2017-09-05
        // 4.1 갑작스런 중단에 대한 방어 로직
        // 넘버링 하는 도중 갑작스럽게 중단되면 BXM_LOG_TRX 는 넘버링이 되있는데, BXM_DEFERRED_SEQ 는 반영이 안된 경우가 있음.
        // BXM_LOG_TRX MAX_SEQ 를 가져와서 seqCount 랑 다르면 맞추기
        int maxSeq = getMaxSeq(in, bizDt);
        if (numberingInfo.getLastProcLogSeq().intValue() != maxSeq)
        {
            numberingInfo.setLastProcLogSeq(maxSeq);
            numberingInfo.setProcExecCnt(maxSeq);
            numberingInfo.setDomainId(in.getDomainId());
            updateNumbering(numberingInfo);
        }

        // 5. 넘버링 실행
        BigDecimal beforeProcExecCnt = numberingInfo.getProcExecCnt();
        try
        {
            afterNumberingSeqInfo = executeNumbering(in, numberingInfo, bizDt);
        }
        catch (IllegalStateException e)
        {
            executeErrorProcess(in, bizDt);
            throw new IllegalStateException("Numbering Error Update.");
        }

        // 6. BXM_DEFERRED_SEQ 최신화
        BigDecimal procExecCnt = afterNumberingSeqInfo.getProcExecCnt();
        if (procExecCnt.compareTo(beforeProcExecCnt) != 0)
            updateSeq(afterNumberingSeqInfo);

        // 7. LOG_SEQ 중복인 경우 에러 처리 (방어 로직 추가)
        checkDuplicateLogSeq(in, bizDt);

        // 8. 마지막 LogSeq 리턴8
        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");
        }

    }
SWLab Bankware Global
  • 전체
  • BXM
  • BXCM
  • BXCP
  • BXI
제품 선택 시 더 정확한 매뉴얼 가이드를 제공해드립니다.

Copyright© Bankwareglobal All Rights Reserved.