ABAP / FIELD NOTES

COMMIT WORK 직후에 왜 테이블이 아직 비어 있을까

업데이트 태스크에 등록한 가상 키 K-100은 COMMIT WORK 직후 조회에 없을 수 있습니다. AND WAIT가 없으면 sy-subrc 0은 성공이 아니고, 암시적 커밋과 롤백과 종료는 서로 다른 결말입니다.

COMMIT WORK 바로 다음 줄에서 같은 키를 읽었는데 행이 없다면, 대화 프로그램이 직접 쓴 변경인지, 업데이트 태스크에 등록만 한 변경인지부터 갈라야 합니다. 등록은 그 줄에서 행을 만들지 않습니다. AND WAIT가 없고 로컬 업데이트가 아니면, COMMIT WORK는 업데이트 워크 프로세스를 기다리지 않습니다.

키 K-100은 이 순서를 보여 주는 가상 값입니다. 회사 시스템에서 실행하거나 조회한 결과가 아닙니다. 범위는 ABAP 키워드 문서의 클래식 업데이트 태스크입니다. RAP의 저장 순서와 ABAP Cloud에서 같은 문장이 같은 뜻인지는 확인하지 않았습니다. 문장의 동작은 ABAP 키워드 문서의 COMMIT WORK에 적혀 있고, 그 페이지의 본문은 영어입니다.

등록만 했을 때 테이블은 왜 그대로일까

CALL FUNCTION ... IN UPDATE TASK는 업데이트 함수 모듈을 나중에 실행하라고 등록합니다. 그 줄에서 모듈은 돌지 않습니다. 동기 업데이트와 비동기 업데이트는 각자의 업데이트 세션에서 돌고, 로컬 업데이트만 현재 워크 프로세스의 새 내부 세션에서 돕니다. 업데이트가 도는 동안에는 금지된 문을 쓸 수 없고, 권한 검사도 하지 않습니다.

가상 예는 높은 우선순위 모듈 하나가 K-100을 쓰도록 등록된 상태입니다. COMMIT WORK와 ROLLBACK WORK는 아직 없습니다. 테이블에 K-100은 없습니다. 직접 INSERT한 변경은 지금 열린 데이터베이스 LUW의 일이고, 업데이트 태스크에 맡긴 변경은 등록 기록입니다.

가상 키 K-100을 업데이트 태스크에 등록만 한 그림. 대화 프로그램은 IN UPDATE TASK로 모듈을 나중에 실행하라고 등록하고, 그 줄에서 모듈은 돌지 않는다. 등록 기록은 높은 우선순위 모듈 하나와 키 K-100이며 실행 기록이 아니다. 테이블에는 K-100 행이 없고, 직접 INSERT한 변경과는 다른 요청이다.
등록은 K-100을 적어 두는 일이지, 그 줄에서 행을 만드는 일이 아닙니다.

COMMIT WORK만으로는 왜 다음 줄의 조회가 비어 있을까

COMMIT WORK는 현재 SAP LUW를 닫고 새 LUW를 연 뒤, 그때까지 등록된 모듈의 처리를 시작합니다. 높은 우선순위 모듈은 문서에서 VB1이라고 하며, 등록 순서대로 하나의 데이터베이스 LUW에서 실행됩니다. AND WAIT가 없고 로컬 업데이트가 아니면 프로그램은 그 프로세스를 기다리지 않습니다. 다음 SELECT가 K-100을 못 볼 수 있습니다. 행이 없다는 것은 등록이 없었다는 뜻이 아닙니다.

AND WAIT가 없으면 sy-subrc는 항상 0입니다. 그 0은 업데이트가 성공했다는 값이 아닙니다. 업데이트가 나중에 실패해도 이 시점의 값은 0입니다.

낮은 우선순위 모듈은 문서에서 VB2라고 합니다. 높은 우선순위 모듈이 모두 성공한 뒤에, 등록 순서대로, 별도의 공유 데이터베이스 LUW에서 실행됩니다. 모듈이 도는 동안 데이터베이스 커밋과 롤백, 업데이트 제어 변경은 허용되지 않고 런타임 오류가 됩니다. 모듈 안의 COMMIT WORK는 COMMIT_IN_POSTING입니다. COMMIT WORK는 열린 데이터베이스 연결도 커밋하므로, 대화에서 직접 쓴 변경과 모듈이 쓸 행은 같은 시각의 일이 아닙니다.

AND WAIT 없이 COMMIT WORK만 한 가상 예의 그림. SAP LUW를 닫고 등록된 모듈 처리를 시작하지만, 호출 측은 업데이트 워크 프로세스를 기다리지 않는다. 바로 다음 SELECT에서 K-100이 아직 없을 수 있고, 없음이 등록 실패를 뜻하지는 않는다. AND WAIT가 없으면 sy-subrc는 항상 0이며 그 0은 업데이트 성공이 아니다.
기다리지 않으면 다음 조회가 K-100보다 먼저 달릴 수 있습니다. 그때의 sy-subrc 0은 성공 보고가 아닙니다.

AND WAIT는 무엇을 기다리고, sy-subrc는 무엇을 말할까

AND WAIT가 있고 로컬이 아니면, 프로그램은 업데이트 워크 프로세스가 높은 우선순위 모듈을 실행할 때까지 다음 문장으로 가지 않습니다. sy-subrc 0은 그 업데이트가 성공한 것이고, 4는 성공하지 않은 것이므로, 다음 조회로 행이 생겼다고 보면 안 됩니다. 이 값은 낮은 우선순위 모듈이 끝났다는 뜻이 아닙니다. 이 가상 예에서 모듈의 일이 K-100을 쓰는 것이라면, 0은 그 쓰기가 높은 우선순위 처리 안에서 끝났다는 뜻으로 읽습니다. 그 조회는 실행하지 않았습니다.

로컬 업데이트는 SET UPDATE TASK LOCAL을 등록보다 먼저 켜야 합니다. 문서의 업데이트 예제는 로컬 업데이트가 항상 동기로, 현재 워크 프로세스에서 수행된다고 설명합니다. 업데이트의 런타임 오류가 나면 업데이트 워크 프로세스는 데이터베이스 롤백을 하고 해당 테이블에 기록한 뒤, 항목을 만든 사용자에게 SAPMail로 알립니다. 문서는 원인을 고친 뒤 취소된 항목을 다시 업데이트할 수 있다고 적습니다. 그 재처리는 실행하지 않았습니다.

COMMIT WORK AND WAIT의 sy-subrc를 구분한 그림. 0은 높은 우선순위 모듈이 성공했다는 뜻이고, 프로그램은 그때까지 다음 줄로 가지 않는다. 4는 높은 우선순위 모듈이 성공하지 않았다는 뜻이며 AND WAIT가 없으면 이 4는 나오지 않는다. 낮은 우선순위 VB2는 높은 우선순위가 성공한 뒤에 별도의 공유 데이터베이스 LUW에서 실행되고, AND WAIT의 대기는 VB2까지가 아니다.
0과 4는 높은 우선순위 모듈의 결과입니다. 낮은 우선순위 모듈이 끝났는지는 이 값이 말하지 않습니다.

암시적 커밋, 롤백, 종료는 왜 다른 결말일까

작업 프로세스가 바뀌면 암시적 데이터베이스 커밋이 납니다. 클래식 다이얼로그 단계가 끝날 때와, 문서 예제의 WAIT UP TO가 그 자리입니다. 예제는 등록들 사이에 WAIT UP TO를 두고, 그때까지 등록된 모듈은 나중의 COMMIT WORK가 실행한다고 설명합니다. 암시적 커밋은 SAP LUW를 닫지 않습니다. COMMIT CONNECTION과 DB_COMMIT도 데이터베이스 커밋일 뿐, 등록된 모듈을 실행하지 않습니다. SAP LUW를 닫고 그에 딸린 동작을 하는 문은 COMMIT WORK입니다.

ROLLBACK WORK는 현재 SAP LUW를 닫고 변경 요청을 취소합니다. IN UPDATE TASK 등록을 문서가 VB...라고 적는 테이블에서 지우므로, K-100 모듈은 실행되지 않습니다. PERFORM ON COMMIT 등록도 지우고, PERFORM ON ROLLBACK 서브루틴은 실행합니다. COMMIT WORK 없이 프로그램이나 내부 세션이 끝나면 등록된 절차는 무시됩니다. 업데이트 함수 모듈 기록은 데이터베이스에 남지만 더 이상 실행되지 않습니다.

CALL DIALOG으로 호출된 프로그램 안의 COMMIT WORK는 예외입니다. ON COMMIT 서브루틴과 업데이트 모듈을 시작하지 않고, 현재 SAP LUW도 닫지 않습니다. SAP LUW는 호출한 쪽의 COMMIT WORK가 닫을 수 있습니다. 그래도 그 안의 문은 데이터베이스 커밋은 일으킵니다. 모든 COMMIT WORK가 업데이트를 시작한다고 보면 이 호출에서는 어긋납니다.

같은 가상 등록 K-100의 세 결말을 비교한 그림. 대화 단계의 끝이나 WAIT UP TO의 암시적 데이터베이스 커밋은 데이터베이스 LUW만 끝내고 등록은 남긴다. ROLLBACK WORK는 VB...에서 등록을 지워 모듈이 실행되지 않게 한다. COMMIT WORK 없이 프로그램이나 내부 세션이 끝나면 등록된 절차는 무시되고, 기록은 남지만 더 이상 실행되지 않는다.
암시적 커밋은 등록을 남겨 두고, 롤백은 등록을 지우며, 커밋 없는 종료는 기록을 실행할 수 없는 상태로 남깁니다.

다음 조회가 비어 있을 때 먼저 적을 질문은 네 가지입니다.

  • 그 변경이 IN UPDATE TASK 등록인지, 대화 처리에서 직접 쓴 것인지.
  • COMMIT WORK에 AND WAIT가 있었는지, 로컬 업데이트가 등록보다 먼저 켜져 있었는지.
  • 그 전에 ROLLBACK WORK가 있었는지, 또는 COMMIT WORK 없이 세션이 끝났는지.
  • sy-subrc 0을 성공으로 읽었다면, AND WAIT가 실제로 있었는지.

번호가 비는 현상은 다른 질문입니다. 메인 메모리 버퍼에서 번호가 건너뛰는 경우는 업데이트 등록과 같은 기록이 아닙니다. K-100이 안 보이면 삭제보다 먼저, 모듈이 아직 돌지 않았는지, 등록이 지워졌는지, 실행되지 못한 채 남았는지를 구분합니다.

END OF NOTE목록으로
COMMENTS BOX

이 기록에 대화를 더해 주세요.

궁금한 점, 다른 접근, 직접 해 본 결과를 나눠 주세요.

최신순

로그인 상태 확인 중…

댓글을 불러오는 중…