ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ABAP/AMDP INSERT-SELECT-UPDATE 트랜잭션(LUW) 완전 정리
    SAP 2026. 7. 9. 19:28

    abap_amdp_luw_transaction.pdf
    0.12MB
    abap_amdp_luw_transaction.html
    0.02MB

     

     

    ABAP/AMDP INSERT-SELECT-UPDATE 트랜잭션(LUW) 완전 정리

    ABAP/AMDP INSERT → SELECT → UPDATE 트랜잭션(LUW) 완전 정리

    INSERT → SELECT → UPDATE 흐름에서 중간에 COMMIT이 없는 경우의 동작, ABAP와 AMDP의 트랜잭션 관계, read-your-own-writes 원칙, delta merge, 그리고 실무에서 자주 발생하는 "COMMIT 후에도 SELECT가 안 되는" 현상까지 정리한다.

    1. 기본 개념: DB LUW와 트랜잭션 가시성

    INSERT → SELECT → UPDATE 사이에 COMMIT이 없으면, 이 세 작업은 모두 하나의 미확정 DB 트랜잭션(DB LUW) 안에서 실행된다.

    • 같은 세션(커넥션) 안에서는 자신이 방금 INSERT한 값을 SELECT로 즉시 조회할 수 있다 — read-your-own-writes
    • COMMIT WORK가 끝까지 호출되지 않으면, 세션 종료·에러·타임아웃 시 자동 롤백되어 INSERT/UPDATE 모두 없었던 일이 된다
    • SAP 락 오브젝트(ENQUEUE)는 DB 트랜잭션과 별개로 관리되며, COMMIT WORK 또는 명시적 DEQUEUE 전까지 유지된다

    2. ABAP 실행 vs AMDP 실행의 차이

    트랜잭션 관점에서는 차이가 없다. 둘 다 같은 default DB connection을 공유하고 같은 DB LUW에 참여한다.

    • AMDP 프레임워크는 명시적으로 autocommit을 꺼놓기 때문에, AMDP 호출 전후로 암묵적 커밋이 발생하지 않는다
    • AMDP 안에서 실행한 UPDATE도 그 이전 ABAP의 INSERT와 같은 미확정 트랜잭션에 묶인다
    ⚠️ 예외: AMDP가 USING 절 등으로 별도 DB 커넥션(secondary connection)을 명시적으로 여는 경우에만 별도 트랜잭션이 되어 이 원칙이 깨진다.

    3. ABAP와 AMDP 혼용

    가능하며, 실무 표준 패턴이다.

    INSERT zsome_table FROM ls_data.
    DATA(lv_result) = NEW zcl_amdp_class( )->do_update_via_amdp( ).
    UPDATE zsome_table SET status = 'X' WHERE ...
    COMMIT WORK.   " 전체를 원자적으로 확정

    마지막 COMMIT WORK 한 번으로 ABAP INSERT + AMDP UPDATE + ABAP UPDATE가 all-or-nothing으로 반영된다.

    4. read-your-own-writes 개념

    • 격리 수준(isolation level)과 무관하게 항상 보장된다
    • 격리 수준은 "남의 미커밋 데이터를 내가 볼지"를 정하는 규칙이지, "내가 쓴 데이터를 내가 볼지"를 정하는 규칙이 아니기 때문
    • 다른 세션은 COMMIT 전까지 해당 데이터를 볼 수 없음

    5. INSERT 시점의 lock 처리

    레벨자동 여부설명
    DB(HANA) 행 잠금자동INSERT 순간 해당 row/인덱스 엔트리에 배타 락, COMMIT/ROLLBACK 시 자동 해제
    SAP ENQUEUE(애플리케이션 락)자동 아님ENQUEUE_E<락오브젝트> 명시적 호출 필요, COMMIT WORK/DEQUEUE 전까지 유지

    6. AMDP "unmanaged" 케이스

    AMDP 자체에는 공식적인 managed/unmanaged 구분이 없다(그 용어는 RAP BO 개념). 실제로 트랜잭션 동작이 달라지는 경우는 다음과 같다.

    • secondary connection 사용 시: 별도 트랜잭션이 되어 read-your-own-writes가 깨지고, COMMIT WORK와 별개로 관리해야 하며 부분 반영(partial commit) 불일치 위험이 있음
    • Native SQL로 직접 프로시저 호출 시: default connection을 그대로 쓴다면 트랜잭션 동작은 AMDP와 동일 — 사라지는 건 소스 버전관리·타입 매핑 등 개발 편의 기능뿐

    7. 스냅샷은 애플리케이션에서 직접 조회 가능한가

    불가능하다. MVCC 스냅샷은 HANA 엔진 내부의 row 버전 체인이며, 애플리케이션은 SELECT 결과로만 간접 확인 가능하다. 시스템 뷰(M_TRANSACTIONS 등)로 트랜잭션 메타정보는 볼 수 있으나 "현재 스냅샷 버전"을 직접 조회하는 기능은 없다.

    8. HANA 전용 개념인가, 다른 DB도 동일한가

    보편적 원리다. read-your-own-writes는 특정 DB 기술이 아니라 트랜잭션 원자성(Atomicity)을 지키기 위한 최소 요구조건이므로, MVCC(HANA, Oracle, PostgreSQL, MySQL InnoDB) 방식이든 락 기반(SQL Server 기본) 방식이든 공통으로 보장된다.

    DB동시성 제어 방식기본 격리 수준
    HANAMVCC (delta/main store 버전 체인)READ COMMITTED
    OracleMVCC (Undo 세그먼트 기반)READ COMMITTED
    PostgreSQLMVCC (row versioning)READ COMMITTED
    MySQL (InnoDB)MVCCREPEATABLE READ
    SQL Server (기본)락 기반(2PL)READ COMMITTED (락 기반)

    Oracle의 Undo 세그먼트가 하던 역할을 HANA는 delta store의 row 버전 체인이 대신할 뿐, 애플리케이션 동작은 동일하다.

    9. 스냅샷 계산 시점 (정확한 설명)

    각 SQL 문(statement)이 실행되는 시점마다, "그 순간까지 커밋된 데이터 + 자기 자신이 이번 트랜잭션에서 만든 변경"으로 스냅샷이 새로 계산된다.

    격리 수준스냅샷 갱신 시점
    READ COMMITTED (HANA 기본값)매 SQL 문마다 새로 계산
    REPEATABLE READ / SERIALIZABLE트랜잭션 시작 시점에 한 번만 고정
    💡 HANA 기본값에서는 같은 트랜잭션 안에서도 SELECT를 두 번 날리면, 그 사이 다른 세션이 커밋한 변경이 두 번째 SELECT에 반영될 수 있다. 단, read-your-own-writes 원칙 자체는 격리 수준과 무관하게 그대로 유지된다 — 내가 쓴 값은 항상 보인다.

    10. INSERT/UPDATE 시 reorg(delta merge) 처리

    HANA 컬럼 스토어는 INSERT/UPDATE를 곧바로 압축된 컬럼 구조(main store)에 쓰지 않는다.

    동작 방식

    • INSERT/UPDATE는 먼저 delta store(행 지향, 비압축, 쓰기에 최적화된 임시 영역)에 기록된다
    • delta store에 데이터가 쌓이면, 일정 조건(크기 임계치, 시간 주기, 수동 명령)에 따라 delta merge(reorg)가 발생하여 압축·정렬된 main store로 병합된다
    • MERGE DELTA OF <table> 명령으로 수동 실행하거나, 시스템이 자동으로 백그라운드에서 수행한다(auto merge)

    트랜잭션/가시성에 미치는 영향

    없음. delta merge는 순수 물리적 저장구조 재구성 작업이며, MVCC 버전 관리는 delta store와 main store에 걸쳐 일관되게 동작한다. merge가 일어나는 중이라도 트랜잭션 격리성이나 read-your-own-writes 원칙에는 영향이 없다. 다만 merge 도중 짧은 배타 락(merge lock)이 걸릴 수 있어 대용량 배치 직후 일시적 성능 지연이 발생할 수 있다.

    ⚠️ 대량 INSERT/UPDATE 배치 처리에서는 delta merge가 반복 트리거되며 성능 저하가 발생할 수 있다 — 배치 종료 후 한 번에 MERGE DELTA를 명시적으로 호출하는 방식을 권장한다. 이는 순수 성능/저장구조 문제이며, 커밋 여부나 read-your-own-writes 같은 트랜잭션 정합성 문제와는 별개다.

    11. INSERT 후 COMMIT이 있고, 바로 SELECT하는 경우 — read-your-own-writes에 해당하는가?

    엄밀히 말하면 해당하지 않는다.

    • read-your-own-writes는 "커밋 전(미확정) 상태의 내 변경을, 나만 볼 수 있다"는 것을 가리키는 개념
    • 이미 COMMIT이 일어난 뒤라면, 그 데이터는 더 이상 "나만의 미확정 데이터"가 아니라 모두에게 공개된 확정 데이터
    • 즉 COMMIT 이후의 SELECT는 read-your-own-writes라는 특수 예외 규칙이 작동하는 게 아니라, 그냥 일반적인 "커밋된 데이터 읽기"일 뿐이다
    💡 결론: COMMIT 후 바로 SELECT하면 보이지만, 그건 read-your-own-writes 덕분이 아니라 커밋된 데이터는 원래 누구나 볼 수 있다는 당연한 트랜잭션 규칙 때문이다. read-your-own-writes는 어디까지나 커밋 전(pre-commit) 구간에서만 의미를 갖는 개념이다.

    12. COMMIT 후 SELECT에서 데이터를 못 읽어오는 경우 — 원인 분석

    이론상 "커밋했으니 무조건 보여야 한다"는 원칙과 실무 상황이 어긋나 보일 때가 있는데, 대부분 트랜잭션 정합성 문제가 아니라 SAP 아키텍처 특유의 비동기 처리·버퍼링·인프라 지연 때문이다.

    12-1. COMMIT WORK의 비동기 업데이트(V1/V2 Update Task)

    COMMIT WORK는 단순히 DB 커밋만 하는 게 아니라 업데이트 태스크(update task)를 트리거하는 역할도 한다.

    • CALL FUNCTION ... IN UPDATE TASK로 등록된 로직은 COMMIT WORK 시점에 별도의 업데이트 프로세스(work process)로 넘어가서 처리됨
    • V1 업데이트: 동기적이지만 별도 work process에서 실행 — 호출 프로그램과는 별개의 타이밍
    • V2 업데이트: 완전 비동기 — 시스템 부하 시 몇 초~몇 분 뒤 처리될 수 있음
    • COMMIT WORK 실행 직후 프로그램이 곧바로 다음 SELECT로 넘어가는데, 이 시점에 실제 DB write가 아직 완료되지 않았을 수 있음
    💡 해결책: COMMIT WORK AND WAIT. — 업데이트 태스크 완료까지 대기 후 다음 문장 진행. 단 성능 저하가 있으므로 순차 보장이 꼭 필요한 곳에만 사용.

    12-2. SAP 테이블 버퍼링(Table Buffering)

    • 테이블이 버퍼링 설정(single record, generic, full buffer)되어 있으면 SELECT가 DB가 아니라 애플리케이션 서버의 로컬 메모리 버퍼에서 값을 읽음
    • COMMIT 시 버퍼 무효화(invalidation) 신호가 다른 AS(application server) 인스턴스로 전파되는데, 즉시가 아니라 약간의 지연을 두고 전파됨
    • 다중 AS 환경에서 "AS1 INSERT+COMMIT → AS2 바로 SELECT"하는 경우, AS2가 아직 무효화 신호를 못 받아 캐시된 이전 값을 반환할 수 있음

    확인: SE11에서 해당 테이블의 버퍼링 설정 확인. 문제라면 SELECT ... BYPASSING BUFFER로 DB를 직접 조회하도록 강제 가능.

    12-3. HANA 시스템 복제(System Replication) / Read-Enabled Secondary

    HA 구성이나 읽기 부하 분산을 위해 read-enabled secondary를 운영 중이라면, 그쪽으로 라우팅된 SELECT는 복제 지연(replication lag) 때문에 방금 커밋된 데이터가 아직 도착하지 않았을 수 있다. 순수 인프라 레벨 이슈로 ABAP/AMDP 코드와는 무관하다.

    12-4. 병렬 처리/비동기 RFC 타이밍 문제

    CALL FUNCTION ... STARTING NEW TASK 등으로 병렬 처리하는 경우, 호출한 쪽이 COMMIT을 먼저 했더라도 병렬 프로세스가 그 시점 이전 스냅샷 기준으로 이미 시작됐다면 값이 안 보일 수 있다 — 타이밍 경쟁(race condition) 문제.

    12-5. 실무 체크리스트

    원인확인 방법대응
    V1/V2 업데이트 지연SM13(업데이트 로그)에서 지연/에러 확인COMMIT WORK AND WAIT
    테이블 버퍼링SE11 → 기술설정 → 버퍼링 여부BYPASSING BUFFER 또는 버퍼링 해제
    HANA 복제 지연시스템 replication 모니터(HDBSQL, DBACOCKPIT)쓰기 직후 조회는 primary로 라우팅
    병렬/비동기 타이밍프로그램 로직상 실행 순서 재검토동기화 지점(WAIT, 세마포어 등) 추가
    ⚠️ "COMMIT 후 바로 SELECT했는데 안 보인다"는 트랜잭션 원자성이 깨진 게 아니라, 대부분 COMMIT WORK가 트리거하는 비동기 업데이트 태스크가 아직 안 끝났거나 버퍼/복제본이 최신 상태로 갱신되지 않은 것이 원인이다. 순서 보장이 중요한 로직이라면 COMMIT WORK AND WAIT을 우선 검토한다.

    📌 핵심 요약

    1. COMMIT 전까지는 모든 변경이 하나의 미확정 트랜잭션 — ABAP/AMDP 구분 없이 동일하게 취급됨
    2. 내가 쓴 값은 언제나 내가 볼 수 있음(read-your-own-writes), 남은 COMMIT 전까지 못 봄
    3. COMMIT 이후엔 read-your-own-writes가 아니라 일반적인 "커밋된 데이터 읽기" — 모두에게 동일하게 보임
    4. ABAP ↔ AMDP는 default connection을 쓰는 한 완전히 같은 LUW — 자유롭게 혼용 가능, COMMIT은 마지막에 ABAP에서 한 번만
    5. DB 행 락은 INSERT 시 자동, SAP 애플리케이션 락(ENQUEUE)은 수동
    6. delta merge(reorg)는 저장구조 재구성 작업일 뿐, 트랜잭션 정합성과는 무관
    7. COMMIT 후 SELECT가 안 보이는 현상은 대부분 V1/V2 업데이트 지연, 테이블 버퍼링, 복제 지연, 병렬 타이밍 문제 — 트랜잭션 원자성 문제가 아님

    ⚠️ 주의해야 할 점

    • secondary connection을 쓰는 AMDP는 별도 트랜잭션이 되어 read-your-own-writes가 깨지고, 부분 반영(partial commit) 위험이 생김 — 특별한 이유 없으면 피할 것
    • HANA 기본 격리 수준(READ COMMITTED)에서는 같은 트랜잭션 내 반복 조회 시 값이 바뀔 수 있음 — 재고 체크처럼 같은 값을 여러 번 참조하는 로직에서는 FOR UPDATE로 락을 걸거나, 최초 조회값을 변수에 저장해 재사용할 것
    • AMDP 메소드 내부에서 별도로 COMMIT을 호출하지 말 것 — 전체 ABAP LUW의 원자성이 깨질 수 있음
    • INSERT가 DB 행 락을 자동으로 걸어주는 것과 별개로, 비즈니스 로직 차원의 중복 방지는 SAP ENQUEUE를 직접 설계해야 함
    • 대량 배치 INSERT/UPDATE 시 delta merge로 인한 성능 저하 가능 — 배치 종료 후 명시적 MERGE DELTA 호출 고려
    • COMMIT 이후의 SELECT를 read-your-own-writes 사례로 혼동하지 말 것 — 그건 그냥 일반 커밋 데이터 조회임
    • COMMIT 후 SELECT가 안 되는 경우, 코드 로직보다 V1/V2 업데이트·버퍼링·복제 지연 등 인프라 요인을 먼저 점검할 것
    #ABAP #AMDP #SAP_HANA #LUW #트랜잭션 #read-your-own-writes #MVCC #delta_merge #COMMIT_WORK #테이블버퍼링 #V1V2업데이트
Designed by Tistory.