如何在推进中创建新的事务范围

时间:2016-02-08 13:00:31

标签: php mysql transactions propel

我们在mysql数据库上使用propel作为orm。 我们正在更改几个表并在事务期间调用外部服务。在这两者之间,我们在日志记录表中记录这些操作和响应。如果发生错误,我们还原操作但希望保留日志消息。目前,日志消息使用相同的事务范围,并且将使用事务还原。

我是否使用

获得新连接和事务管理器
$con = Propel::getConnection(DATABASE_NAME);

或者我必须检查是否返回了相同的连接

PSEUDO CODE

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

1 个答案:

答案 0 :(得分:1)

选择Propel的好选择。您有两种选择,可以将日志记录封装在自己的事务中,也可以使用Propel独有支持的嵌套事务。

第一个只需要write_log函数中的事务性:

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

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

第二种方法是启动嵌套事务并确保只回滚内部事务:

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();
}