Loading

Salesforce WebService 에러 - '커밋되지 않은 보류 중인 작업이 있습니다. 호출 전 커밋 또는 롤백하십시오.'

게시 일자: Apr 24, 2026
상세 설명


커밋되지 않은 보류 중인 트랜잭션이 있는 경우 콜아웃이 허용되지 않습니다. 예를 들어 DML 작업 전에 저장 지점을 설정한 경우 해당 작업의 결과에 따라 저장 지점을 커밋하거나 롤백하는 콜아웃을 만들 수 없습니다.

때로는 레코드를 처리하는 동안 비즈니스 규칙에 따라, 이미 실행된 부분적인 작업(DML 문)을 롤백하여 다른 방향으로 처리를 계속해야 할 수 있습니다. Apex는 저장 지점, 즉 요청 내에서 특정 시점의 데이터베이스 상태를 지정하는 지점을 생성하는 기능을 제공합니다. 저장 지점 이후에 발생하는 모든 DML 문은 폐기될 수 있으며, 데이터베이스는 저장 지점를 생성했을 때의 상태로 복원됩니다.

예제 시나리오:
저장 지점 작업을 수행하려고 할 경우 계정을 삽입하여 중복을 찾고 롤백한 후 웹 서비스 콜아웃을 통해 계정 데이터를 외부 시스템으로 보냅니다. 하지만 웹 서비스가 호출되기 전에 다음 오류가 표시됩니다. '커밋되지 않은 보류 중인 작업이 있습니다. 호출 전 커밋 또는 롤백하십시오.'

 

다음 단계에서 이 오류가 발생할 수 있습니다. 
  1. UI에 정보를 입력하여 새 고객을 만들고 저장을 클릭합니다. 
  2. 시스템에서 저장 지점을 생성한 후 고객 레코드를 삽입합니다. 
  3. 중복을 찾기 위해 트리거가 발생합니다.
  4. 중복이 없는 경우 2단계에서 설정한 저장 지점에 따라 고객 레코드 삽입을 롤백합니다. 
  5. 시스템에서 웹 서비스를 호출하여 새 고객 데이터를 외부 시스템으로 보내고 외부 ID를 다시 가져옵니다.
  6. 시스템에서 새 고객을 외부 ID와 함께 SFDC에 저장합니다.

 

다른 시나리오로서 System.enqueueJob, Database.executeBatch 및 Future 메서드와 같은 비동기 대기열 추가 프로세스를 통한 커밋되지 않은 작업이 있을수 있습니다.
솔루션


요청 컨텍스트에서 보류 중인 트랜잭션으로 콜아웃을 만들 수 없습니다. 또한 명시적으로 커밋을 수행할 수 없습니다. 따라서 해결 방법은 별도의 컨텍스트에서 콜아웃을 만드는 것입니다. 
콜아웃 전에는 DML 작업을 수행할 수 없습니다. 모든 DML 작업은 콜아웃을 완료한 후에만 호출해야 합니다. 그러므로 웹 서비스 콜아웃을 먼저 만든 후에 요청을 저장하십시오.
여러 개의 콜아웃을 만들 경우 모든 요청을 목록 또는 맵에 저장하고 저장한 콜아웃을 게시합니다.

다음 순서의 단계를 따르면 작동하게 됩니다. 
쿼리
콜아웃
쿼리
콜아웃
삽입
콜아웃
콜아웃 
콜아웃
삽입 또는 업데이트

다음의 시나리오 단계는 작동하지 않습니다.
콜아웃
삽입
콜아웃 <---- 여기에서 작동하지 않습니다.

  1. 트랜잭션을 커밋하거나 데이터 변경 전에 콜아웃을 만들거나 콜아웃을 @future 메서드로 이동해야 합니다(@future 주석을 웹 서비스 메서드에 배치).
  2. 두 개의 개별 Ajax 프로세스로 트랜잭션을 분할합니다. 먼저 레코드를 삽입한 후 콜아웃을 수행하면 새로 삽입된 레코드를 업데이트할 수 있습니다.
  3. 레코드를 저장한 후 콜아웃을 수행하는 두 번째 콜백을 만들어 "로드 중" 메시지가 있는 임시 페이지를 통해 사용자에게 응답할 수 있습니다. 매끄럽게 보일 수 있도록 연속하는 AJAX 호출을 만들어 사용자가 "저장" 버튼을 클릭하면 레코드를 저장하고, "저장" 버튼 클릭 시 "로드 중" 메시지가 사용자에게 표시되도록 콜아웃을 만들 수도 있습니다.
  4. 웹 서비스 메서드에 @future 주석을 배치하지 않으려면 개체를 삽입하는 작업을 실행한 후 commandButton의 oncomplete 이벤트에서 웹 서비스 콜아웃을 실행할 수 있습니다. 그 후 PageReference를 반환하여 사용자에게 즉각적인 피드백을 제공합니다. 웹 서비스 콜아웃에서 오류를 반환할 경우 개체를 삭제하고 사용자를 동일한 페이지로 다시 복귀시킵니다.


VisualForce Page

<apex:actionFunction name="executeWS" action="{!executeWS}"></apex:actionFunction>
 <apex:commandButton value="Save" action="{!save}" oncomplete="executeWS()" />


Controller

public PageReference save() {
 insert obj;
}
public PageReference executeWS(){
 obj = [SELECT ...];
 try{
 callout ws;
 } catch(System.Exception ex){
 delete obj;
 ApexPages.addMessages(e);
 return null;
 }
 return new PageReference('/' + id);
}

참고: Future 또는 Queueable 의 큐에 추가는 커밋되지 않은 작업이므로 콜아웃 전에는 해당 작업을 수행할 수 없습니다.

자세한 정보는 관련 링크 오류 - '트리거의 콜아웃은 현재 지원되지 않습니다.'를 참조하십시오.
 

Knowledge 기사 번호

000385708

 
로드 중
Salesforce Help | Article