Fala, Diego!
O método flush
commita a transação. Todas as instruções antes do flush estão armazenadas mas ainda não foram enviadas pro banco.
O controle de transações normalmente é feito fora do repositório, então o ideal seria chamar o flush depois do repositório ter finalizado seu trabalho.
Eu estava fazendo alguns testes de serviços transacionais há algum tempo. Vê se esses exemplos do meu GitHub te dão um norte:
Aí no final eu faria algo do tipo:
$repository = // Doctrine ou Pdo repository
$session = // Doctrine ou Pdo session
$command = // AddQuestionCommand com os dados necessários
$addQuestion = new AddQuestion($repository, new QuestionFactory());
$addQuestionWithinTransaction = new TransactionalApplicationService($addQuestion, $session);
$addQuestionWithinTransaction->executeAtomically($command);
A implementação pode ser melhorada. Esse projeto eu fiz só pra testar algumas possibilidades. Mas dá pra tirar algumas ideias daí. Eu coloquei os arquivos numa ordem que você precisaria pra entender, mas pode ver todos os códigos do repositório se quiser entender mais a fundo...