1

コードのブロックにトランザクションを使用する必要があります。これは複数の挿入で構成されています。コードのブロック全体をtrycatchブロック内に配置し、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

ここで注意すべきことは、tryブロックがどれほど大きくても、それによってスローされた例外をキャッチし、それに応じてアクションを実行できる必要があるということです。

しかし、ここであなたは使用しました

catch (Exception $exc)

さまざまな例外をキャッチすることはできません。これは、デバッグして例外の正しい理由を示すのに役立ちます。

また、トランザクションの場合は、単一の試行ブロックに含める必要があります

于 2012-11-26T05:31:58.257 に答える
1

実際には、Dbで発生した場合にロックを回避できるように、より小さなトランザクション境界に焦点を当てる必要がありますが、実行するかどうかにかかわらず、コードのブロック全体が必要になる場合があります。その場合、ほとんどチャンスがありません。コードを可能な限りモジュール化します。

于 2012-11-26T05:29:21.623 に答える