카테고리 없음

MIXED_DML_OPERATION Exception

으농농이 2024. 8. 8. 17:29

배치 개발을 많이 하다보니까 요즘 계속 exception 내용만 남기네 ^^...

 

[정의]

단일 트랜잭션 내에서 설정(Setup) 객체와 비설정(Non-setup) 객체에 대해 동시에 데이터 조작 언어(DML) 작업을 수행할 때 발생하는 Exception 

 

예를들어서

설정 개체는 아래와 같다 

 

  • User
  • Group
  • GroupMember
  • Profile
  • PermissionSet
  • PermissionSetAssignment
  • ObjectPermissions
  • FieldPermissions
  • Queue
  • Role
  • UserRole

그외 custom object , standard obj 는 비설정 객체에 보함이 된다 

 

이 DML 이 한 배치에 동시에 일어나면 , 저 에러가 어김없이 나온다...

 

해결방안 

Batch 외 일반 class에서는 @future을 사용하면되지만,,

Batch 안에서는 @future 을 사용할 수 없기에..

 

queable  로 트랜잭션을 분리해서 처리를 해야한다. 

 

예를들어 batch 안에 excute 안에서 

A__c 라는 custom object 를 delete 하면서 GroupMember 를 삭제해야하는 로직을 예를들면 

아래와 같이 코드를 작성했다 

public void execute(Database.BatchableContext BC, List<User> userList) {

		try{
			Set<Id> userIdSet = (new Map<Id,User>(userList)).keySet();

			List<A__c> aList = [
				SELECT Id
				FROM A__c
				WHERE b__c IN :userIdSet
			];
			if(aList.Size()>0){
				delete aList;
			}

			// 트랜잭션 분리! 
			System.enqueueJob(new delMember(userIdSet));

		}catch(Exception e){

        }
		
    }

이렇게 짜고 

 

finish 아래 quealbe class를 추가하던가 .. 별도 클래스를 새로 만들어 사용하는방법이 있다. 

public class delMember implements Queueable {
// 삭제 로직
}

 

 

이렇게 분리를 해주면 한 배치가 돌때 해당 Exception이 뜨지 않고 잘 돌아가는걸 확인할 수 있다.