Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Доктрина 1.2: Использование postDelete для удаления связанных файлов в файловой системе с поддержкой транзакций

Автор вопроса: mattalxndrОтветов: 1

Этот вопрос является своего рода расширением этого вопроса:

Выполните некоторую очистку при удалении записи в Symfony/Doctrine

Я делаю это, и все работает нормально, за исключением одной проблемы: если удаление завершается ошибкой и транзакция никогда не фиксируется, метод postDelete все равно выполняется, и файлы все равно удаляются.

Что было бы хорошим способом избежать этого?

transactionsdoctrine

Ответы

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы