2012-11-26 64 views
1

我需要使用事務處理一段代碼,它由多個插入組成。在try.catch塊之前啓動事務是否在try catch塊中包含全部代碼是一個好習慣。然後,對於捕獲的任何異常,回滾其他事務提交。建議,php mysql事務插入塊中的多個表

基本問題:

  • 是不好的做法,一個交易週期內有整個代碼塊?
  • 如果這是一個不好的做法,什麼是處理這個問題的好方法,爲什麼?

下面是一個代碼塊:

$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'); 
    } 

回答

1

其實,我們應該着眼於更小的交易邊界,這樣如果發生在Db的,但有時我們需要整個代碼塊要麼執行,我們能夠避免任何鎖或者沒有,所以在這種情況下,我們幾乎沒有任何機會留下,你需要儘可能地模塊化你的代碼。

1

這裏要注意的是,try塊的大小應該是多大,我們應該能夠捕獲它所拋出的異常並相應採取行動。

但在這裏你已經使用

catch (Exception $exc) 

,你將無法捕捉不同的異常。這有助於調試並顯示異常的正確原因。

此外,如果其交易時,我們必須有它在一個try塊

+0

你說的意思是「你將不能夠捕獲不同的例外。」如果您針對不同的異常提及了不同的catch塊,那麼我在我的代碼中就已經有了它,我只是使用了一個更通用的方法。順便說一句,我相信這抓住了所有的例外,但這不是最好的做法。 –

+0

這就是我所說的 - 「順便說一句,我相信這抓住了所有的例外,雖然這不是最好的做法」 –