1

我需要对一段代码使用事务,它由多个插入组成。在 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');
    }
4

2 回答 2

1

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

于 2012-11-26T05:29:21.623 回答
1

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

但是在这里你已经使用了

catch (Exception $exc)

您将无法捕获不同的异常。这有助于调试和显示异常的正确原因。

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

于 2012-11-26T05:31:58.257 回答