Lock Select

업무 요건상 동시에 처리할 수 없는 데이터를 Select할 때 Oracle에서 제공하는 FOR UPDATE 키워드를 사용하여 Lock 처리한다. WAIT 시간은 업무에 따라 알맞게 설정한다.

1. 형식

NOWAIT : 해당 Row가 Lock 상태일 때 바로 SQL 에러(ORA-00054)를 발생시킨다.

WAIT X : 해당 Row가 Lock 상태일 때 X초 재시도 후 SQL 에러(ORA-30006)을 발생시킨다.

SELECT
     A.ROWID AS "rowId"
     , A.FEDU_EMP_NO AS feduEmpNo
     , A.FEDU_EMP_NM AS feduEmpNm
     , A.FEDU_OCCP_NM AS feduOccpNm
  FROM SMP_EMP_TST A
 WHERE A.FEDU_EMP_NO = #{feduEmpNo}
FOR UPDATE [NOWAIT | WAIT seconds]

2. 개발 및 유의사항

조회 Row가 Lock 상태이면 DasCannotAcquireLockException(caused by ORA-00054/ORA-30006)이 발생한다.

try {
    dSmpEmpTst001.selectOneLock01(dSmpEmpTst000Dto, LockUpdate.FOR_UPDATE);
} catch (DasCannotAcquireLockException e) {
    // DB LOCK 타임아웃 발생시 처리로직
}

3. DBIO 샘플

Options 에 [Lock Update] 를 체크한다. 단건/다건 Select 구문에 ROWID와 FOR UPDATE 구문을 추가한다.

lockselect001
Figure 1. Lock Select 화면

팝업에서 작성된 SQL의 스키마를 지정한다.

lockselect002
Figure 2. Lock Select 화면

4. Bean 샘플

@BxmCategory(logicalName = "Multi-Update 2")
public int modifyEmpInfBySelectOneLock(List<DSmpEmpTst000Dto> input)
        throws DefaultApplicationException {

    logger.debug("============== START ==============");
    logger.debug("input = {}", input);

    dSmpEmpTst001 = DefaultApplicationContext.getBean(dSmpEmpTst001, DSmpEmpTst001.class);

    int modifyCnt = 0;

    /**
     * @BXMType Loop
     */
    for (DSmpEmpTst000Dto dSmpEmpTst000Dto : input)
    {
        /**
         * @BXMType DbioCall
         * @Desc Get lock for a row to update
         */
        LockUpdater<DSmpEmpTst000Dto> lockUpdaterDSmpEmpTst = dSmpEmpTst001.selectOneLock01(dSmpEmpTst000Dto, LockUpdate.FOR_UPDATE);

        DSmpEmpTst000Dto lockDSmpEmpTst000Dto = lockUpdaterDSmpEmpTst.updatable();

        /**
         * @BXMType LogicalArea
         * @Desc Mapping data to update
         */
        {
            // Generated by code generator [[
            lockDSmpEmpTst000Dto.setFeduEmpNo(dSmpEmpTst000Dto.getFeduEmpNo());
            lockDSmpEmpTst000Dto.setFeduEmpNm(dSmpEmpTst000Dto.getFeduEmpNm());
            lockDSmpEmpTst000Dto.setFeduOccpNm(dSmpEmpTst000Dto.getFeduOccpNm());
            lockDSmpEmpTst000Dto.setFeduMngrEmpNo(dSmpEmpTst000Dto.getFeduMngrEmpNo());
            lockDSmpEmpTst000Dto.setFeduHireDt(dSmpEmpTst000Dto.getFeduHireDt());
            lockDSmpEmpTst000Dto.setFeduPayAmt(dSmpEmpTst000Dto.getFeduPayAmt());
            lockDSmpEmpTst000Dto.setFeduDeptNo(dSmpEmpTst000Dto.getFeduDeptNo());
            // Generated by code generator ]]
        }

        /**
         * @BXMType DbioCall
         * Update single employee info
         */
        modifyCnt = lockUpdaterDSmpEmpTst.update();

        /**
         * @BXMType IF
         * @Desc If there are no modified row
         */
        if (modifyCnt != 1) {
            /**
             * @BXMType ApplicationException
             * @Desc throw application exception if there are no modified row
             */
            throw new DefaultApplicationException("BXME60003", new Object[] { lockDSmpEmpTst000Dto.getFeduEmpNo() } );
        }
    }

    logger.debug("output = {}", modifyCnt);
    logger.debug("============== END ==============");

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

Copyright© Bankwareglobal All Rights Reserved.