Dataverse 롤업 vs 계산 열: 우리가 빠진 비동기 함정

발행: (2026년 5월 24일 AM 11:52 GMT+9)
11 분 소요
원문: Dev.to

Source: Dev.to

거래 데스크 대시보드에 계정별 진행 중인 기회 총액이 표시되었습니다. 계정당 총액은 롤업 열이었습니다. 사용자는 대시보드를 열어 총액을 확인하고 결정을 내렸습니다. 그 뒤에 누군가 새로운 기회를 추가하고 같은 계정을 다시 확인했지만, 계정의 총액은 변하지 않았습니다.
15분 뒤에 새로 고침해도 변하지 않았고, 한 시간 뒤에야 변했습니다. 롤업 열은 문서에 명시된 대로 정확히 동작했으며, 팀은 이를 실시간 집계라고 오해한 것이었습니다.

아래는 계산 열과 롤업 열의 차이점이며, 대시보드가 최신 정보를 보여야 할 때 우리가 현재 사용하는 패턴입니다.

계산 열

행이 읽힐 때마다 값을 계산합니다. 열이 두 다른 열을 더한다면, 행이 로드될 때마다(폼 보기, API 호출, 보기 행) Dataverse가 합계를 계산합니다. 결과는 언제나 최신이며, 필요할 때마다 다시 도출됩니다.

롤업 열

값을 일정에 따라 계산합니다. 기본 일정은 12시간마다이며, 열당 1시간까지 조정할 수 있습니다. 자식 레코드 금액을 합산하는 롤업은 일정이 실행될 때 현재 자식 상태를 읽고, 결과를 저장한 뒤 다음 일정이 올 때까지 저장된 값을 제공합니다.

두 열 모두 정의(수식)를 솔루션에 저장하고, 소비 코드에서는 동일하게 보입니다. 하지만 런타임 동작은 근본적으로 다릅니다.

계산 열이 적합한 경우

  • 수식이 동일 행의 필드 또는 부모 행의 필드(lookup을 통해)만을 참조할 때
  • 계산이 가볍고(산술, 문자열 연결, 조건문) 비용이 적을 때
  • 값을 읽을 때마다 최신 상태가 필요할 때

롤업 열이 적합한 경우

  • 수식이 다수의 자식 레코드에 대해 집계(SUM, COUNT, AVG, MIN, MAX)할 때
  • 기본 데이터는 자주 변하지만 집계가 초 단위로 최신일 필요는 없을 때
  • 비동기 재계산 스케줄링이 허용될 때

자식을 집계하는 계산 열은 허용되지 않습니다. Dataverse는 성능 문제 때문에 이를 차단합니다—계정을 읽을 때마다 모든 기회를 조회해야 하기 때문입니다. 롤업은 플랫폼이 제공하는 해결책으로, 집계를 미리 계산해 캐시된 값을 제공하는 방식입니다.

흔히 겪는 시나리오

비즈니스 사용자가 대시보드에서 자식 레코드의 누적 합계를 보고 실제와 일치하기를 기대합니다. 사용자가 “계정 양식에 표시되는 총액에 모든 연결된 기회 금액이 포함돼야 한다”고 말하면 팀은 롤업 열을 만들고 대시보드에 표시합니다.
그 후 사용자가 새로운 기회를 만들고 계정을 확인하면 총액이 오래된 값으로 남아 있습니다. 사용자는 숫자가 잘못됐다고 생각하지만, 플랫폼 입장에서는 마지막 스케줄 실행 시점까지 정확한 값이었습니다.

해결 방법은 사용자의 기대치를 낮추는 것(대시보드가 일정에 따라 업데이트됨)이나 구현 방식을 바꾸는 것입니다.

집계가 실제로 최신이어야 할 때

대안 1: 플러그인으로 자식 변경 시 저장된 총액 업데이트

Opportunity(생성, 금액 업데이트, 삭제) 후 작업 플러그인을 만들어 부모 Account의 acme_total_opportunities를 재계산하고 저장합니다.

  • 적합: 중간 규모의 마스터‑디테일 관계(예: 200개의 기회가 드물게 업데이트되는 경우)
  • 한계: 20,000개의 기회가 빈번히 업데이트되는 경우, 각 자식 변경이 부모 쓰기로 이어져 Dataverse 실행 파이프라인이 제한됩니다.

대안 2: 계산 열을 이용한 자식 기여도 계산 후 조회 시 집계

부모에서 직접 자식을 집계할 수는 없지만, 자식 레코드에 계산 열을 만들어 기여도를 정의할 수 있습니다.

acme_attributable_amount = IF(acme_is_counted, amount, 0)   // Opportunity에 적용

그 후 소비자는 이 필드를 사용해 조회 시 합산합니다.

  • 적합: FetchXML에 집계 연산자를 사용할 수 있는 대시보드(SUM을 단일 쿼리로 수행)
  • 제한: Dataverse 폼이나 뷰처럼 집계 쿼리를 지원하지 않는 경우는 사용 불가.
  • 활용: Power BI 보고서, 맞춤 대시보드, 읽기 쿼리를 직접 제어할 수 있는 모든 상황.

대안 3: 1시간 스케줄 롤업 + “Refresh” 버튼

기본 케이스는 기존 롤업을 유지하고, 폼에 버튼을 추가해 CalculateRollupField SDK 요청으로 롤업을 즉시 재계산합니다. 사용자는 “자식을 추가했으니 Refresh를 눌러 총액을 업데이트한다”는 느낌을 가집니다.

  • 적합: 사용량이 급증하는 대시보드—기본 업데이트는 허용하고, 즉시 새로 고침으로 최신성을 보장하고 싶을 때.
  • 활용: 영업 관리 화면, 딜 데스크 검토, 사용자가 새로 고침 의미를 이해하는 시나리오.

롤업 관리 팁

프로젝트에 롤업 열이 3개 이상이면 분기마다 감사를 수행합니다.

  1. 롤업이 아직 사용 중인가?
    롤업은 누적됩니다—요구사항이 사라져도 열은 남아 일정 슬롯을 차지합니다.
  2. 스케줄 빈도가 적절한가?
    데이터가 매시간 변하는데 12시간 롤업이면 오래된 데이터가 많고 비효율적입니다.
  3. 수식이 여전히 올바른가?
    롤업 정의에 포함된 statecode/statuscode 값이 향후 릴리즈에서 의미가 바뀌면, 롤업이 조용히 잘못된 결과를 산출할 수 있습니다.

감사 시간은 프로젝트당 약 20분이며, 절반 정도는 최소 하나의 롤업을 삭제할 수 있고, 3분의 1은 스케줄을 조정해야 합니다.

삭제 시 롤업 동작 특성

  • 자식이 생성되거나 금액이 변경될 때는 롤업이 즉시 업데이트됩니다.
  • 자식이 삭제될 때는 스케줄된 새로 고침이 실행될 때까지 롤업이 업데이트되지 않습니다.

따라서 “자식 삭제 → 롤업 새로 고침 전” 구간에서는 총액이 과대 계산됩니다. 이는 특히 감사 시나리오에서 고통스럽습니다—중복 레코드를 삭제했지만 총액이 최대 12시간 동안 여전히 중복 기여를 표시합니다.

해결 방안

  • 플러그인: 자식 Delete(후 작업) 이벤트에서 CalculateRollupFieldRequest를 호출해 롤업을 즉시 재계산합니다.
  • 더 짧은 스케줄: 삭제가 드물고 일정 지연을 허용할 수 있다면 스케줄을 1시간 이하로 조정합니다.

대부분 테이블이 삭제를 지원하므로, 사용자에게 보이는 지연을 최소화하기 위해 플러그인을 선호합니다.

사용자 안내

롤업 열에는 폼 툴팁이 자동으로 포함됩니다:

“이 총액은 매 N시간마다 새로 고침됩니다. 새 레코드를 추가한 후에는 ‘Refresh’를 클릭하면 즉시 업데이트됩니다.”

툴팁은 필드 설명 한 줄에 불과해 추가 비용이 없으며, “왜 숫자가 오래됐나요?” 라는 티켓을 사전에 방지합니다. 배포하는 모든 롤업에 이 툴팁을 넣고, 인계받은 롤업에도 최초 적용 시 반드시 추가합니다.

0 조회
Back to Blog

관련 글

더 보기 »

내 스킬

프로젝트를 위한 AI 지시문을 만들고, 설치하고, 관리하세요 — 코딩이 필요 없습니다. CREATE 이름을 정하고, 카테고리를 선택하고, 원하는 것을 설명하세요 — 마법사가 자동으로 구성합니다.