建议将php mysql事务插入到块中的多个表中

建议将php mysql事务插入到块中的多个表中,php,mysql,transactions,symfony-1.4,propel,Php,Mysql,Transactions,Symfony 1.4,Propel,我需要将事务用于代码块,它由多个插入组成。将整个代码块放在try-catch块中,在try..catch块之前启动事务,这是一种好的做法。然后,对于捕获到的任何异常,回滚其他事务并提交 基本问题: 在一个事务周期内拥有整个代码块是一种不好的做法吗 如果这是一种不好的做法,那么处理这种情况的好方法是什么?为什么 下面是一段代码: $con = Propel::getConnection(SomeTablePeer::DATABASE_NAME); $con-&g

我需要将事务用于代码块,它由多个插入组成。将整个代码块放在try-catch块中,在try..catch块之前启动事务,这是一种好的做法。然后,对于捕获到的任何异常,回滚其他事务并提交

基本问题:

  • 在一个事务周期内拥有整个代码块是一种不好的做法吗
  • 如果这是一种不好的做法,那么处理这种情况的好方法是什么?为什么
下面是一段代码:

    $con = Propel::getConnection(SomeTablePeer::DATABASE_NAME);        
    $con->beginTransaction();        
    try {
        $currentRevision = $budgetPeriod->getRevision();
        $newRevision = $currentRevision->copy();
        $newRevision->setIdclient($client->getIdclient());            
        $newRevision->setIsLocked(0);
        $newRevision->save();
        $currentRevision->setEffectiveTo($currentDate);
        $currentRevision->save();

        $currentRevisionHasCorporateEntities = $currentRevision->getCorporateEntitys();
        $newOldCorporateEntitiesRelations = array(); 

        foreach ($currentRevisionHasCorporateEntities as $currentRevisionHasCorporateEntity) {

            $newRevisionHasCorporateEntity = $currentRevisionHasCorporateEntity->copy();                
            $newRevisionHasCorporateEntity->save();
        }

     // this continues for a while there are a whole list of insertions based on previous insertion and on and on.
    }catch (Exception $exc) {
        $con->rollback();            
        $this->getUser()->setFlashError('Error occured! Transaction Failed');
    }

实际上,我们应该关注更小的事务边界,这样我们就可以避免在Db中发生任何锁,但有时我们需要执行或不执行整个代码块,所以在这种情况下,我们几乎没有机会了,您需要尽可能地模块化您的代码

这里需要注意的是,无论try块有多大,我们都应该能够捕获它抛出的异常并采取相应的措施

但这里你用过

catch (Exception $exc)
您将无法捕获不同的异常。这有助于调试并显示异常的正确原因

此外,如果它是一个事务,我们必须将它放在一个try块中

您所说的“您将无法捕获不同的异常”是什么意思。如果您将不同的捕获块用于不同的异常,我在这里的代码中确实有它,我只是使用了一个更通用的方法,例如。顺便说一句,我相信这抓住了所有的例外,尽管这不是最好的好做法。这就是我所说的——“顺便说一句,我相信这抓住了所有的例外,尽管这不是最好的好做法”