Этот вопрос является своего рода расширением этого вопроса:
Выполните некоторую очистку при удалении записи в Symfony/Doctrine
Я делаю это, и все работает нормально, за исключением одной проблемы: если удаление завершается ошибкой и транзакция никогда не фиксируется, метод postDelete все равно выполняется, и файлы все равно удаляются.
Что было бы хорошим способом избежать этого?
Ответ 1 · рейтинг 3 · dbellizzi
Если вам нужно инициировать что-то только тогда, когда транзакция действительно была зафиксирована, вам нужно поставить ее в очередь в postDelete, а затем выполнить ее в обработчике postTransactionCommit.
$conn = Doctrine_Manager::connection(...);
$conn->addListener(new TransactionCommitListener());
class TransactionCommitListener extends Doctrine_EventListener {
public function postTransactionCommit(Doctrine_Event $event) {
if ($event->getInvoker()->getConnection()->getTransactionLevel() == 1) {
// do your filesystem deletes here
}
}
public function postTransactionRollback(Doctrine_Event $event) {
// clear your delete queue here
}
}
Обычно я использовал синглтон для хранения очереди и извлекал ее статически. Если вы используете несколько соединений, вам понадобится несколько очередей.
Приведенный выше обработчик фиксации срабатывает только при самой внешней фиксации, именно так Doctrine работает с mysql, поскольку он не предоставляет вложенных транзакций. Если ваша база данных поддерживает вложенные транзакции, и доктрина поддерживает это, вам может потребоваться это изменить.