2010-11-01 30 views
2

Cette question est une sorte d'extension à cette question:Doctrine 1.2: Utilisation postDelete pour supprimer les fichiers associés sur le système de fichiers - avec le soutien des transactions

Perform some cleanup when deleting a record in Symfony/Doctrine

Je fais cela et cela fonctionne bien, sauf pour un problème: si la suppression échoue et que la transaction n'est jamais validée, la méthode postDelete est toujours exécutée et les fichiers sont quand même supprimés.

Quel serait un bon moyen d'éviter cela?

Répondre

3

Si vous avez besoin de déclencher quelque chose que lorsque l'opération a été effectivement commise, vous devez la file d'attente dans postDelete, puis l'exécuter dans un gestionnaire 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 
    } 
} 

J'ai généralement utilisé un singleton à stocker la file d'attente et l'a récupérée statiquement. Si vous utilisez plusieurs connexions, vous devez disposer de plusieurs files d'attente. Le gestionnaire de validation ci-dessus se déclenche uniquement sur la validation la plus externe, c'est-à-dire comment Doctrine fonctionne avec mysql, car elle ne fournit pas de transactions imbriquées. Si votre base de données fournit des transactions imbriquées et que la doctrine le permet, vous devrez peut-être changer cela.