+ Start a Discussion
MJ Kahn / OpFocusMJ Kahn / OpFocus 

Mixed DML Error on CronJobDetail

We have code that does the following:

 

  • Queries CronTrigger to see if there’s an entry for a job with an Id we previously saved in a custom setting.
  • If there is such an entry, calls System.abortJob() to kill that job. If necessary, calls System.abortJob() twice.
  • Schedules the job to run.
  • Saves the Id of the newly-scheduled job in that custom setting

 

Very intermittently, when we save the Id of the newly-scheduled job in the custom setting, we get a Mixed DML error:  First exception on row 0 with id a0E3000000Gj95IEAR; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): OurPkg__Settings__c, original object: CronJobDetail: []

 

The Id (a0E3000000Gj95IEAR) refers to the record for the custom setting.

 

We’re not (of course) touching CronJobDetail directly, and don’t know why we’d get a Mixed DML error for what should be a relatively innocent piece of code, or why the error happens only intermittently. To be clear, we are not doing any direct DML operations on any setup objects -- the closest we come to that is scheduling and aborting jobs.

 

Any thoughts on why we're getting this error, especially only intermittently, and on what we can do to get around it?

 

Thanks.

My OwnMy Own

 

Is your schedule job dealing any User object updates?. I think so, we usually get this error when you try to update User object only. can you please post your code here.

MJ Kahn / OpFocusMJ Kahn / OpFocus

Nope, we're not touching User or any other Setup object directly. We are scheduling and aborting Jobs, so we're touching CronTrigger indirectly -- that's our only interaction with a Setup object.

 

The error message complains about CronJobDetail, which we can't even query directly, let alone perform DML on.

MJ Kahn / OpFocusMJ Kahn / OpFocus

Someone asked for the code. Here's a simplified version of it:

 

// Check if the scheduled job is hung.
// The job can't be scheduled again with the same name so it must be aborted before scheduling it again.
Settings__c settings = Settings__c.getInstance(UserInfo.getOrganizationId())
if (settings.Job_Id__c != null) {
	List<CronTrigger> cronTriggers = [select Id from CronTrigger where Id = :settings.Job_Id__c];
	if (cronTriggers.size() == 1) {
		System.abortJob(jobId);

		try {
			// Sometimes, aborting the job doesn't kill it dead, so if it
			// still exists, abort it again.
			System.abortJob([select Id from CronTrigger where Id = :jobId].Id);
		} catch (Exception ex) {
		}

	}
}

// Schedule the job to run in 65 seconds from now.
// Scheduling the job to run any sooner has proven to result
// in deadlocks in some orgs so 65 seconds is used to be safe.
String scheduleExpression = Datetime.now().addSeconds(65).format('s m H d M ? yyyy');
String jobId = System.Schedule('Our Job', scheduleExpression, new OurJob());

// Save the scheduled job id.
settings.Job_Id__c = jobId;
update settings;

 

We get the Mixed DML error on the last line, when we update our custom object.

 

Sridhar VenkateswaraluSridhar Venkateswaralu

HI All,

 

same Issue. any updates would help?

Same code was working fine earlier.. dont know what the issue could be.

 

Thanks,
Sridhar

MJ Kahn / OpFocusMJ Kahn / OpFocus

Got no real help from Salesforce on this, other than suggestions that we change our design. Try as we might, we couldn't come up with an other design that would allow us to work around the problem.

 

Fortunately, in Winter 13, it's going to be possible for one Batch Apex job's finish() method to launch another Batch Apex job. As a result, we don't have to resort to having the first job's finish() method schedule a job that launches the second Batch Apex job, which greatly reduces our dependence on scheduled jobs. So we think that, once Winter 13 is completely rolled out, we'll be able to work around the problem.

 

I hope the same solution works for you.

Arjun SrivastavaArjun Srivastava

Hi i ran into the same situation  where i am updating a custom object record after scheduling apex class.

I got the this error  MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): Custom_Object__c, original object: CronJobDetail: [].

 

 

Does anyone got any solution? Please share how this error was resolved.

 

Thanks!