Rozwiązuję problem za pomocą wskazówek optymalizatora, określając dokładną kolejność łączenia w poleceniu DELETE:
delete a, b
from b
STRAIGHT_JOIN a on a.id = b.a_id
where a.id = ?;
MySQL najpierw DELETE b wierszy dzięki wskazówce optymalizatora STRAIGHT_JOIN.