How to write in Apex a mass deletion (over 10 000 records, even up to 150 000) of related records that can be safely called from async context, like Batch?
I have two custom objects, lets call them Source__c
(Parent) and Payment__c
(Child). They are connected using Lookup relation. Upon deletion of a Source__c
records, I need to delete all related Payments. For now, I'm using simple Batch that is executed from a before delete trigger. In the future, there might be a batch that will delete a Source
record, and it should delete the Payments
as well, but batch cannot be executed from another batch besides chaining in finish()
. How to approach this safely, either by chaining the deletion somehow or making clear, async-safe exception to prevent such batch from running?
My code currently, part of trigger handler:
public with sharing class SourceTH extends TriggerHandler.DelegateBase {
public override void prepareBefore() {
if (Trigger.isDelete) {
deleteRelatedPayments(Trigger.oldMap.keySet());
}
}
private static void deleteRelatedPayments(Set<String> sourceIds) {
if (!System.isFuture() && !System.isBatch()) {
DeletePaymentsOnSourceBatch.runBatch(sourceIds);
}
else {
// How to make mass delete safely from async context?
}
}
}
Batch class to delete:
public with sharing class DeletePaymentsOnSourceBatch implements Database.Batchable<SObject> {
private final Set<String> sourceIds = new Set<String>();
public static void runBatch(Set<String> sourceIds){
Database.executeBatch(new DeletePaymentsOnSourceBatch(sourceIds), 100);
}
public Database.QueryLocator start(Database.BatchableContext BC) {
return Database.getQueryLocator([
SELECT Id
FROM Payment__c
WHERE Source__c IN :this.sourceIds
]);
}
public void execute(Database.BatchableContext BC, List<SObject> scope) {
delete scope;
}
public void finish(Database.BatchableContext BC) {}
}