2016-02-08 1 views
0

Nous utilisons propel comme orm sur un mysql db. Nous modifions plusieurs tables et appelons des services externes au cours d'une transaction. Entre nous enregistrons ces actions et la réponse dans une table de journalisation. Si une erreur se produit, nous inversons les actions mais souhaitons conserver les messages du journal. À l'heure actuelle, les messages de journalisation utilisent la même étendue de transaction et seront rétablis avec la transaction.Comment créer une nouvelle portée de transaction dans propel

Est-ce que je reçois une nouvelle connexion et TransactionScope avec

$con = Propel::getConnection(DATABASE_NAME); 

ou dois-je vérifier si la même connexion est renvoyée

CODE PSEUDO

public function write_log() 
{ 
    $con = Propel::getConnection(DATABASE_NAME); 

    $log=new Log(); 
    $log->message('foo'); 
    $log->save($con); 
} 

public function change_data() 
{ 
    write_log('start'); 

    $con = Propel::getConnection(DATABASE_NAME); 
    $con->beginTransaction(); 
    try { 
     //this message should stay in the database 
     write_log('change_db_data:'.$new_db_value); 
     //this should be reverted 
     change_db_data($new_db_value); 

     write_log('call webservice_1'); 
     $response=call_webservice_1(); 
     write_log($response); 
     if($response==null) 
     { 
     $con->rollback(); 
     } 

     write_log('call webservice_2'); 
     $response=call_webservice_2(); 
     write_log($response); 
     if($response==null) 
     { 
     $con->rollback(); 
     } 


     $con->commit(); 
    } 
    catch(Exception $e){ 
     $con->rollback(); 
     write_log('error') 
    } 
    write_log('end'); 
} 

Répondre

1

Bon choix picking Propel. Vous avez deux choix, soit encapsuler la journalisation dans leurs propres transactions, soit utiliser une transaction imbriquée, uniquement prise en charge par Propel.

La première exige que transactionnalité dans la fonction write_log:

public function write_log() 
{ 
    $con = Propel::getConnection(DATABASE_NAME); 

    $con->beginTransaction(); 
    $log=new Log(); 
    $log->message('foo'); 
    $log->save($con); 
    $con->commit(); 
} 

La seconde est de commencer une transaction imbriquée et faire en sorte que seule la transaction intérieure est annulée:

public function write_log() 
{ 
    $con = Propel::getConnection(DATABASE_NAME); 

    $log=new Log(); 
    $log->message('foo'); 
    $log->save($con); 
} 

public function change_data() 
{ 
    $con = Propel::getConnection(DATABASE_NAME); 
    $con->beginTransaction(); 
    write_log('start'); 

    $con->beginTransaction(); 
    try { 
     //this message should stay in the database 
     write_log('change_db_data:'.$new_db_value); 
     //this should be reverted 
     change_db_data($new_db_value); 

     write_log('call webservice_1'); 
     $response=call_webservice_1(); 
     write_log($response); 
     if($response==null) 
     { 
     throw new \Exception('Null response.'); 
     } 

     write_log('call webservice_2'); 
     $response=call_webservice_2(); 
     write_log($response); 
     if($response==null) 
     { 
     throw new \Exception('Null response.'); 
     } 

     $con->commit(); 
    } 
    catch(Exception $e){ 
     $con->rollback(); 
     write_log('error') 
    } 
    write_log('end'); 
    $con->commit(); 
}