+1 vote
by (163k points)

We have a custom error logging framework built that currently inserts records to a custom Error Log object. We also have a lot of (chained) Queueables in use because have to update some setup objects - GroupMember, PermissionSetAssignment etc. If for whatever reason, one of these setup object updates fails, we need to log that error as well - without causing a mixed DML error.

One option, obviously, is to make the error logging queueable. But instead of knowing from the point of catching the error that I need the logging to happen asynchronously, I'd like to determine that within the Error Logging framework - whether to insert it synchronously or async'ly. The reason for this is, the change becomes simpler - within the framework and not reevaluating all possible points of entry to update this.

Question: Is there something in Apex that tells me if the current transaction contains a setup object DML or could potentially cause a mixed DML issue?

PS: Currently, we're not looking at redesigning the error logging framework itself like using Platform Events or making fully asynchronous (because of our current implementation of Queueables and depth limitations)

1 Answer

+1 vote
by (163k points)
Best answer

There's no way to tell which objects have been acted upon up to some arbitrary point, other than to know how many rows have been acted upon (via Limits.getDmlRows()). However, MIXED_DML_OPERATION is a catchable exception, so that's the most efficient course of action here. From there, you can decide to either jump to a queueable, or you can fire off a Platform Event with the error information, and have a Platform Event Trigger then log the data. Many developers have moved to the Platform Event model, since it works even if the transaction ultimately fails (assuming immediate delivery is enabled), and also works in Queueable, future, etc contexts.
