Doctrine 1.2: Использование postDelete для удаления связанных файлов в файловой системе - с поддержкой транзакций
Этот вопрос является своего рода расширением этого вопроса:
Выполните некоторую очистку при удалении записи в Symfony/Doctrine
Я делаю это, и он работает нормально, за исключением одной проблемы: если удаление не удается, и транзакция никогда не фиксируется, метод postDelete все еще выполняется, и файлы все равно удаляются.
Что было бы хорошим способом избежать этого?
1 ответ
Если вам нужно инициировать что-то только тогда, когда транзакция фактически была зафиксирована, вам нужно поставить ее в очередь в 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, поскольку он не предоставляет вложенные транзакции. Если ваша база данных предоставляет вложенные транзакции, и доктрина поддерживает это, вам может потребоваться изменить это.