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, поскольку он не предоставляет вложенные транзакции. Если ваша база данных предоставляет вложенные транзакции, и доктрина поддерживает это, вам может потребоваться изменить это.

Другие вопросы по тегам